Skip to content

Instantly share code, notes, and snippets.

@NEExploiT

NEExploiT/vx_ssg.rb Secret

Created Aug 6, 2016
Embed
What would you like to do?
require 'erb'
require 'ProcessMemory.rb'
include ProcessMemory
# 省略記法を許すためのお約束
include ProcessMemoryUtil
# プロセス指定
mem = memoryutil_startup
# ERBで使うのでrefinementsでは不可能
class String
def ssg_escape
gsub(%r{[\\/:,=]}){|s| "\\#{s}" }
end
end
using Module.new{
# ProcessMemoryEx本体次期リリース時に入れるかも
refine ProcessMemoryEx do
def strdup(addr, initial_size = 32, atomic_size: 1, encoding: nil, encode: Encoding::UTF_8)
size = initial_size * atomic_size
fmt = ['C*', 'S*', nil, 'V*'][atomic_size - 1]
buf = nil
encoding ||= [Encoding::UTF_8, Encoding::UTF_16, nil, Encoding::UTF_32][atomic_size - 1]
raise 'unknown atomic_size.' unless fmt
loop{
buf = ptr_fmt(addr, size, fmt).take_while{|atom| atom != 0 }
break unless buf.size == size
size *= 2
}
if encoding == encode
buf.pack(fmt).force_encoding(encoding)
else
buf.pack(fmt).encode(encode, encoding)
end
end
end
}
rgss_addr, rgss = mem.modules.detect{|(_, name)| /^RGSS\d+[EJ]?\.dll$/ =~ name }
vx_ace = false
sym_addr = case rgss
when /RGSS10\dJ\.dll/ then 0x1836BC + rgss_addr
when /RGSS20\dJ\.dll/ then 0x18A23C + rgss_addr
when /RGSS30\d\.dll/
vx_ace = true
0x25a2ac + rgss_addr
when nil
raise 'Target is not RGSS'
else
raise "#{rgss} isn't match"
end
sym_tbl = ptr(sym_addr)
h = {}
raise 'sry packed entry is not supported' if vx_ace && ptr(sym_tbl + 8).odd?
num_bins = mem.ptr(sym_tbl + 4)
# puts format("#{rgss}: 0x%08X", rgss_addr),
# format('[%08X] == %08X', sym_addr, sym_tbl), "BINS: #{num_bins}", '-' * 64
bins = mem.ptr_fmt(mem.ptr(sym_tbl + 12), num_bins * 4, 'V*')
bins.each do |entry|
it = entry
while it != 0
key = mem.ptr(it + 4)
key_str = if vx_ace
flg = mem.ptr(key)
noembed = flg & 1 << 13
if noembed != 0
mem.strdup(mem.ptr(key + 12))
else
mem.strdup(key + 8)
end
else
mem.strdup(key)
end
record = mem.ptr(it + 8)
h[key_str] = record
it = mem.ptr(it + 12)
end
end
@get_addr = lambda{|addr|
case addr
when :global
case rgss
when /RGSS20(\d)J\.dll/ then "(MName::#{rgss})+0x18B018"
else
raise 'Not implemented by now, sorry!'
end
else
raise 'Not implemented by now, sorry!'
end
}
def rgss_globals
@get_addr[:global]
end
def make_expr_xp(key, base = nil)
r = [
format('0x%04X=>key;', key),
case base
when Symbol
"[:#{@get_addr[base]}:]=>tmp;"
when /^\(MName::RGSS/ then "[:#{base}:]=>tmp;"
when nil then '[:[:[:[:$base+0x08:]+0x00:]+0x04:]+0x08:]=>tmp;'
else
raise "sorry. not implemented for #{base.inspect}"
end,
*%w[
[:$tmp+0x04:]=>modulo;
($modulo!=0)*$modulo=>modulo1;$modulo==0=>modulo2;
$modulo1|$modulo2=>modulo;
($key%$modulo)*4=>cns;
[:$tmp+0x0C:]=>base;
[:$base+$cns:]=>tmp0;([:$tmp0:]==$key)=>mul0;
]
]
1.upto(9) do |it|
r << "[:$tmp#{it - 1}+0x0C:]=>tmp#{it};([:$tmp#{it}:]==$key)=>mul#{it};"
end
r << 0.upto(9).map{|it|
"($tmp#{it}*$mul#{it})"
}.join('|') + '=>base;'
r.join("\n")
end
keys = h
ERB.new(<<EOS.encode('cp932'), nil, '%-').run
SSG for SpoilerAL ver 6.1
[script]
[title]TODO: TITLE
[maker]TODO: MAKER
[creator]TODO: Author original: RICK
[process]<%= mem.modules.first[1] %>
[note]wordwrap
<%= Time.now.strftime "%F" %>: 自動生成
TODO: 説明などを書く
[/note]
[involve]Game
[group]main
[size]4
[e_with],signed
[io_fep]($Val*2+1),$Val%2=>mul;($Val-1)/2=>tmp0;$tmp0<0x3FFFFFFF=>mul0;$tmp0>=0x40000000=>mul1;$tmp0-0x80000000=>tmp1;$tmp0*$mul0+$tmp1*$mul1=>tmp;$tmp*$mul
[subject]所持金:calc,@Game->address_money,0,9999999
[/group]
// 所持金
[group]address_money
<%= make_expr_xp keys['$game_party'], :global %>
<%= make_expr_xp keys['@gold'] %>
$base+0x08
[/group]
[/involve]
[replace]0x00,Game->main
[/script]
EOS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.