Skip to content

Commit b74c476

Browse files
authored
Emulation dumper improvements 2 (#1541)
* At least we tried * Up * Fix
1 parent d537aa6 commit b74c476

File tree

1 file changed

+242
-21
lines changed

1 file changed

+242
-21
lines changed

reversing/rsz/emulation-dumper.py

Lines changed: 242 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -74,26 +74,204 @@
7474
# these are chains we'll use for testing on games we are encountering issues with
7575
# so we don't need to parse the entire JSON dump
7676
default_chains = {
77-
"via.render.Mesh": {
77+
# This things is obsfucated to hell, if someone gonna do it in the future just use a memory dump with it
78+
# Tried to map kernel user data, TEB, local thread storage, but looks like it will not gonna accept dummy value that easily
79+
# "via.navigation.FilterSet": {
80+
# "address": "14ed9c9e0",
81+
# "crc": "704b0605",
82+
# "deserializer_chain": [
83+
# {
84+
# "address": "0x14b3fa1d0",
85+
# "name": "via.Object"
86+
# },
87+
# {
88+
# "address": "0x14af9d7c0",
89+
# "name": "System.Object"
90+
# },
91+
# {
92+
# "address": "0x14b42b2f0",
93+
# "name": "via.navigation.FilterSet"
94+
# }
95+
# ],
96+
# },
97+
# "via.render.Mesh": {
98+
# "address": "14ee7d8a0",
99+
# "crc": "d74182f1",
100+
# "deserializer_chain": [
101+
# {
102+
# "address": "0x14b3fa1d0",
103+
# "name": "via.Object"
104+
# },
105+
# {
106+
# "address": "0x14af9d7c0",
107+
# "name": "System.Object"
108+
# },
109+
# {
110+
# "address": "0x140001000",
111+
# "name": "via.Component"
112+
# },
113+
# {
114+
# "address": "0x14affc350",
115+
# "name": "via.render.Mesh"
116+
# }
117+
# ],
118+
# },
119+
"via.motion.ActorMotion": {
120+
"address": "14ead2390",
121+
"crc": "e3a6fb73",
78122
"deserializer_chain": [
79123
{
80-
"address": "0x14b34c9c0",
124+
"address": "0x14b3fa1d0",
81125
"name": "via.Object"
82126
},
83127
{
84-
"address": "0x14aeedf90",
128+
"address": "0x14af9d7c0",
85129
"name": "System.Object"
86130
},
87131
{
88132
"address": "0x140001000",
89133
"name": "via.Component"
90134
},
91135
{
92-
"address": "0x14af4d7a0",
93-
"name": "via.render.Mesh"
136+
"address": "0x14cfeae60",
137+
"name": "via.motion.SecondaryAnimation"
138+
},
139+
{
140+
"address": "0x14aded460",
141+
"name": "via.motion.ActorMotion"
94142
}
95-
],
96-
}
143+
]
144+
},
145+
# "app.ChainSub": {
146+
# "address": "14e8d4890",
147+
# "crc": "55ddee1f",
148+
# "deserializer_chain": [
149+
# {
150+
# "address": "0x14b3fa1d0",
151+
# "name": "via.Object"
152+
# },
153+
# {
154+
# "address": "0x14af9d7c0",
155+
# "name": "System.Object"
156+
# },
157+
# {
158+
# "address": "0x140001000",
159+
# "name": "via.Component"
160+
# },
161+
# {
162+
# "address": "0x14cfeae60",
163+
# "name": "via.motion.SecondaryAnimation"
164+
# },
165+
# {
166+
# "address": "0x14cfeae60",
167+
# "name": "via.motion.SecondaryEventListener"
168+
# },
169+
# {
170+
# "address": "0x14ade8ef0",
171+
# "name": "via.motion.Chain"
172+
# }
173+
# ],
174+
# },
175+
# "app.ChainSub2": {
176+
# "address": "14ed77640",
177+
# "crc": "814aaf36",
178+
# "deserializer_chain": [
179+
# {
180+
# "address": "0x14b3fa1d0",
181+
# "name": "via.Object"
182+
# },
183+
# {
184+
# "address": "0x14af9d7c0",
185+
# "name": "System.Object"
186+
# },
187+
# {
188+
# "address": "0x140001000",
189+
# "name": "via.Component"
190+
# },
191+
# {
192+
# "address": "0x14cfeae60",
193+
# "name": "via.motion.SecondaryAnimation"
194+
# },
195+
# {
196+
# "address": "0x14cfeae60",
197+
# "name": "via.motion.SecondaryEventListener"
198+
# },
199+
# {
200+
# "address": "0x14ade9340",
201+
# "name": "via.motion.Chain2"
202+
# }
203+
# ],
204+
# },
205+
# "via.motion.IkMultiLookAt2": {
206+
# "address": "14ea24420",
207+
# "crc": "8479fa27",
208+
# "deserializer_chain": [
209+
# {
210+
# "address": "0x14b3fa1d0",
211+
# "name": "via.Object"
212+
# },
213+
# {
214+
# "address": "0x14af9d7c0",
215+
# "name": "System.Object"
216+
# },
217+
# {
218+
# "address": "0x140001000",
219+
# "name": "via.Component"
220+
# },
221+
# {
222+
# "address": "0x14cfeae60",
223+
# "name": "via.motion.SecondaryAnimation"
224+
# },
225+
# {
226+
# "address": "0x14029aa70",
227+
# "name": "via.motion.IkMultiLookAt2"
228+
# }
229+
# ],
230+
# },
231+
# "via.motion.JointExprGraphLayer": {
232+
# "address": "14e9a78d0",
233+
# "crc": "2d18c265",
234+
# "deserializer_chain": [
235+
# {
236+
# "address": "0x14b3fa1d0",
237+
# "name": "via.Object"
238+
# },
239+
# {
240+
# "address": "0x14af9d7c0",
241+
# "name": "System.Object"
242+
# },
243+
# {
244+
# "address": "0x1403452a0",
245+
# "name": "via.motion.JointExprGraphLayer"
246+
# }
247+
# ],
248+
# },
249+
# "via.motion.JointExprGraph": {
250+
# "address": "14ec81c40",
251+
# "crc": "deb2bb18",
252+
# "deserializer_chain": [
253+
# {
254+
# "address": "0x14b3fa1d0",
255+
# "name": "via.Object"
256+
# },
257+
# {
258+
# "address": "0x14af9d7c0",
259+
# "name": "System.Object"
260+
# },
261+
# {
262+
# "address": "0x140001000",
263+
# "name": "via.Component"
264+
# },
265+
# {
266+
# "address": "0x14cfea840",
267+
# "name": "via.motion.Constraint"
268+
# },
269+
# {
270+
# "address": "0x1402c87f0",
271+
# "name": "via.motion.JointExprGraph"
272+
# }
273+
# ],
274+
# }
97275
}
98276

99277
class Allocator:
@@ -180,9 +358,27 @@ def hook_mem_invalid(emu, access, address, size, value, frame):
180358

181359
import traceback
182360

361+
def get_last_frame_offset(frame, delta=0):
362+
prev_layout = frame["layout"][-1] if len(frame["layout"]) > 0 else None
363+
expected_offset = 0
364+
365+
if prev_layout is None:
366+
return 0
367+
368+
# so this is probably confusing but anyways "offset" is actually AFTER the data
369+
if prev_layout["string"] == False and prev_layout["list"] == False:
370+
expected_offset = ((prev_layout["offset"] + delta) + (frame["last_alignment"] - 1)) & ~(frame["last_alignment"] - 1)
371+
elif prev_layout["string"] == True:
372+
expected_offset = ((prev_layout["offset"] + delta) + (frame["last_alignment"] - 1)) & ~(frame["last_alignment"] - 1)
373+
elif prev_layout["list"] == True:
374+
expected_offset = ((prev_layout["element"]["offset"] + delta) + (frame["last_alignment"] - 1)) & ~(frame["last_alignment"] - 1)
375+
376+
return expected_offset
377+
183378
def hook_code(emu, address, size, frame):
184379
# print("%x" % address)
185380

381+
frame["previous_context"] = frame["context"] if "context" in frame else None
186382
frame["context"] = pickle.dumps(emu.context_save())
187383
cs = frame["cs"]
188384
deserialize_arg = frame["deserialize_arg"]
@@ -363,10 +559,35 @@ def hook_code(emu, address, size, frame):
363559

364560
if last_dis.mnemonic == "and" and last_dis.operands[1].type == X86_OP_IMM and last_dis.operands[0].reg == frame["last_deserialize_reg"]:
365561
# print("0x%X alignment detected" % (~last_dis.operands[1].imm + 1))
562+
expected_alignment = (~last_dis.operands[1].imm + 1)
563+
564+
# The if is to stop inline stuffs
565+
if frame["last_deserialize_cur"] >= frame["max_deserialize_cur"]:
566+
previous_context_obj = pickle.loads(frame["previous_context"]) if frame["previous_context"] != None else None
567+
if previous_context_obj == None:
568+
print("Previous context is None. It should not be for the alignment instruction. 0x%X" % lex)
569+
570+
increased_pointer_val = previous_context_obj.reg_read(last_dis.operands[0].reg)
571+
delta_before_and = increased_pointer_val - frame["last_deserialize_cur"]
572+
573+
if delta_before_and != expected_alignment - 1:
574+
print("Expected alignment of 0x%X doesn't match actual increased pointer value of 0x%X (delta 0x%X) at 0x%X. Probably a skipped member" % (expected_alignment, increased_pointer_val, delta_before_and, lex))
575+
576+
probale_element_size = delta_before_and - (expected_alignment - 1)
577+
previous_member_offset = get_last_frame_offset(frame)
578+
579+
frame["layout"].append({
580+
"size": probale_element_size,
581+
"element_size": probale_element_size,
582+
"element": None,
583+
"align": 1,
584+
"string": False,
585+
"list": False,
586+
"offset": previous_member_offset
587+
})
366588

367-
# Set this because we don't want the actual byte count screwing up
368589
frame["last_deserialize_cur"] = val
369-
frame["last_alignment"] = (~last_dis.operands[1].imm + 1)
590+
frame["last_alignment"] = expected_alignment
370591

371592
frame["last_deserialize_reg_val"] = val
372593
elif frame["last_alignment"] == 4 and last_dis.group(X86_GRP_BRANCH_RELATIVE):
@@ -528,17 +749,17 @@ def hook_code(emu, address, size, frame):
528749
print("Stream pointer shifted by an unaccounted amount! 0x%X -> 0x%X (%i)" % (expected_offset, actual_offset, len(frame["layout"])))
529750
print("Last layout: ", prev_layout)
530751

531-
# Add padding to the layout
532-
padding_needed = actual_offset - expected_offset
533-
frame["layout"].append({
534-
"size": padding_needed,
535-
"element_size": padding_needed,
536-
"element": None,
537-
"align": 1,
538-
"string": False,
539-
"list": False,
540-
"offset": deserialize_cur - padding_needed - frame["buffer_start"]
541-
})
752+
# # Add padding to the layout
753+
# padding_needed = actual_offset - expected_offset
754+
# frame["layout"].append({
755+
# "size": padding_needed,
756+
# "element_size": padding_needed,
757+
# "element": None,
758+
# "align": 1,
759+
# "string": False,
760+
# "list": False,
761+
# "offset": deserialize_cur - padding_needed - frame["buffer_start"]
762+
# })
542763

543764
frame["layout"].append({
544765
"size": delta,
@@ -736,7 +957,7 @@ def main(p, il2cpp_path="il2cpp_dump.json", test_mode=False):
736957

737958
highest_alloc = (highest_alloc + 1024 + (map_align - 1)) & ~(map_align - 1)
738959
allocator = Allocator(emu, highest_alloc + (1024 + (map_align - 1)) & ~(map_align - 1))
739-
960+
740961
'''
741962
pe.parse_data_directories()
742963
for entry in pe.DIRECTORY_ENTRY_IMPORT:

0 commit comments

Comments
 (0)