首先恭喜0x401 Team首次在CTF比赛中夺得第一名,顺便和学弟AK了逆向,战队能取得今天的成绩离不开队员的努力。但是不得不承认另一个原因是,很多强队的火力都被隔壁RCTF吸引了,我们还需要继续努力:
自从上次强网杯unicorn那题以来我就一直对unicorn很感兴趣,但平时又没有用unicorn解决实际问题的场景,这次羊城杯总算碰到了,借此机会学习一下unicorn。OddCode这题有大量花指令和垃圾跳转,手动分析几乎不可能,如果使用unicorn模拟执行会方便很多。
比赛时一直爆肝到凌晨5点才把这题弄出来(被屑出题人的大小写坑了3个小时),本文的解法是我赛后优化之后的解法。
首先这是一个32位的可执行文件:
没有main函数,程序直接从start函数开始执行,首先是一段校验输入格式的代码:
一个很奇怪的远跳转,一开始在IDA看了半天没明白是什么意思,用WinDbg调试后才发现IDA的反汇编有问题:
实际上是一个远跳转到33:2E5310
这个地址,远跳转有一个隐形的操作,他会将代码段寄存器CS设置为跳转到的这个段对应的段选择子,这里执行完了远跳转之后,CS的值被置为0x33:
这里涉及一个我之前折腾自制操作系统时接触到的一个知识点——在Windows中,程序可以通过修改代码段寄存器切换32位模式和64位模式,当CS为0x33时,CPU按64位模式执行指令,当CS为0x23,时,CPU按32位模式执行指令。执行完这个远跳转后,程序跳转到2E5310这个地址(也就是下一条指令),CPU切换到64位模式执行,所以接下来的代码都要按64位模式解析。
这个技术的一个典型应用是在恶意代码领域,参考:天堂之门(Heaven’s Gate)技术的详细分析
切换到64位模式后,执行sub_2E1010函数:
接下来一段代码的作用是将CS的值改回0x23,切回32位模式:
最后根据sub_2E1010函数的返回值判断输入是否正确,所以本题的关键是sub_2E1010函数:
先到回到这个部分,远跳转前的两个lea语句相当于是传递参数,把input存入esi,把key存入edi:
key是一个16字节的数组,推测之后加密或者校验输入的时候会用上:
从sub_2E1010函数开始的代码要用64位模式查看:
从这里开始有大量的垃圾代码和花指令,手动分析了半天都没找到关键代码,于是我决定用unicorn写一个模拟调试器帮我找到关键代码。
最开始看到用unicorn实现调试器的思路是在这篇文章:汇编与反汇编神器Unicorn。里面用到的调试器代码貌似出自无名侠:
我们也来写个简单的调试器来模拟64位代码的执行,并且实现一个tracer,用来跟踪代码块执行的轨迹:
unicorn可以hook代码块执行,但是会被花指令干扰,所以这里通过hook指令执行,再判断当前的地址
是否与上次执行的地址+上一条指令的长度
是否相等来判断是否发生了代码块跳转:
模拟执行的过程中会莫名其妙报错,所以直接加了一个try,最后打印出来的轨迹如下:
这么多代码块一个个去手动分析不太现实,于是再加一个hook来hook输入和key的访问操作,来帮助我们找到了访问了输入和key的指令所在的代码块,加上:
输出:
通过内存访问hook我们得到了几个很重要的信息:
第三、四个特点是一个伏笔,之后我们会利用这个性质对flag进行爆破。
接下来看到访问了输入的几段代码,这些代码的作用是将第一个字节读入到al,第二个字节读入到bl:
...
从这里开始,顺着我们之前打印出的轨迹往后再分析一会还能发现这样的代码:
说明程序确实是将16进制两字节的输入转换成了对应的16进制数。
再来看到访问了key的代码块:
我们再修改一下trace函数,通过capstone反汇编引擎找到执行到的cmp指令和test指令的地址:
输出:
可以看到在读取key之后执行的cmp指令只有一个,位于2E38E7这个地址,代码如下,大致可以确定是flag加密后比较的代码,比对成功的话不会执行jnz跳转:
所以我们可以通过记录程序第几次执行到了2E38EF这个地址,来判断比较成功比对了几个字节,通过这种方法来爆破flag。
再改一下trace函数:
爆破flag的函数get_flag:
这里选择的字符集为b'1234567890abcdefABCDEF',包括了小写的字母,比赛的时候我是根据traces手动分析加密流程,被大小写坑了几个小时。爆破结果如下:
from
unicorn
import
*
from
unicorn.x86_const
import
*
ADDRESS
=
0x2E1000
INPUT_ADDRESS
=
0x2E701D
KEY_ADDRESS
=
0x2E705C
with
open
(
'OddCode.exe'
,
'rb'
) as
file
:
file
.seek(
0x400
)
X64_CODE
=
file
.read(
0x4269
)
class
Unidbg:
def
__init__(
self
, flag):
mu
=
Uc(UC_ARCH_X86, UC_MODE_64)
mu.mem_map(ADDRESS,
0x1000000
)
mu.mem_write(ADDRESS, X64_CODE)
mu.mem_write(INPUT_ADDRESS, flag)
mu.mem_write(KEY_ADDRESS, b
'\x90\xF0\x70\x7C\x52\x05\x91\x90\xAA\xDA\x8F\xFA\x7B\xBC\x79\x4D'
)
mu.reg_write(UC_X86_REG_RAX,
1
)
mu.reg_write(UC_X86_REG_RBX,
0x51902D
)
mu.reg_write(UC_X86_REG_RCX,
0xD86649D8
)
mu.reg_write(UC_X86_REG_RDX,
0x2E701C
)
mu.reg_write(UC_X86_REG_RSI, INPUT_ADDRESS)
mu.reg_write(UC_X86_REG_RDI, KEY_ADDRESS)
mu.reg_write(UC_X86_REG_RBP,
0x6FFBBC
)
mu.reg_write(UC_X86_REG_RSP,
0x6FFBAC
)
mu.reg_write(UC_X86_REG_RIP,
0x2E1010
)
mu.hook_add(UC_HOOK_CODE,
self
.trace)
self
.mu
=
mu
self
.except_addr
=
0
self
.traces
=
[]
def
trace(
self
, mu, address, size, data):
if
address !
=
self
.except_addr:
self
.traces.append(address)
self
.except_addr
=
address
+
size
def
start(
self
):
try
:
self
.mu.emu_start(
0x2E1010
,
-
1
)
except
:
pass
print
([
hex
(addr)
for
addr
in
self
.traces])
Unidbg(b
'SangFor{00000000000000000000000000000000}'
).start()
from
unicorn
import
*
from
unicorn.x86_const
import
*
ADDRESS
=
0x2E1000
INPUT_ADDRESS
=
0x2E701D
KEY_ADDRESS
=
0x2E705C
with
open
(
'OddCode.exe'
,
'rb'
) as
file
:
file
.seek(
0x400
)
X64_CODE
=
file
.read(
0x4269
)
class
Unidbg:
def
__init__(
self
, flag):
mu
=
Uc(UC_ARCH_X86, UC_MODE_64)
mu.mem_map(ADDRESS,
0x1000000
)
mu.mem_write(ADDRESS, X64_CODE)
mu.mem_write(INPUT_ADDRESS, flag)
mu.mem_write(KEY_ADDRESS, b
'\x90\xF0\x70\x7C\x52\x05\x91\x90\xAA\xDA\x8F\xFA\x7B\xBC\x79\x4D'
)
mu.reg_write(UC_X86_REG_RAX,
1
)
mu.reg_write(UC_X86_REG_RBX,
0x51902D
)
mu.reg_write(UC_X86_REG_RCX,
0xD86649D8
)
mu.reg_write(UC_X86_REG_RDX,
0x2E701C
)
mu.reg_write(UC_X86_REG_RSI, INPUT_ADDRESS)
mu.reg_write(UC_X86_REG_RDI, KEY_ADDRESS)
mu.reg_write(UC_X86_REG_RBP,
0x6FFBBC
)
mu.reg_write(UC_X86_REG_RSP,
0x6FFBAC
)
mu.reg_write(UC_X86_REG_RIP,
0x2E1010
)
mu.hook_add(UC_HOOK_CODE,
self
.trace)
self
.mu
=
mu
self
.except_addr
=
0
self
.traces
=
[]
def
trace(
self
, mu, address, size, data):
if
address !
=
self
.except_addr:
self
.traces.append(address)
self
.except_addr
=
address
+
size
def
start(
self
):
try
:
self
.mu.emu_start(
0x2E1010
,
-
1
)
except
:
pass
print
([
hex
(addr)
for
addr
in
self
.traces])
Unidbg(b
'SangFor{00000000000000000000000000000000}'
).start()
def
trace(
self
, mu, address, size, data):
if
address !
=
self
.except_addr:
self
.traces.append(address)
self
.except_addr
=
address
+
size
def
trace(
self
, mu, address, size, data):
if
address !
=
self
.except_addr:
self
.traces.append(address)
self
.except_addr
=
address
+
size
[
'0x2e1010'
,
'0x2e3634'
,
'0x2e3e1d'
,
'0x2e389c'
,
'0x2e3d9e'
,
'0x2e3b8e'
,
'0x2e37ae'
,
'0x2e3f3a'
,
'0x2e4ee5'
,
'0x2e51ad'
,
'0x2e45f9'
,
'0x2e4e03'
,
'0x2e3c8f'
,
'0x2e4cf1'
,
'0x2e4e96'
,
'0x2e3d49'
,
'0x2e3641'
,
'0x2e4ca8'
,
'0x2e49fd'
,
'0x2e5109'
,
'0x2e4e16'
,
'0x2e382a'
,
'0x2e48f1'
,
'0x2e3ec2'
,
'0x2e4567'
,
'0x2e3a7e'
,
'0x2e4ae0'
,
'0x2e3718'
,
'0x2e402f'
,
'0x2e4ba1'
,
'0x2e4263'
,
'0x2e4441'
,
'0x2e4af2'
,
'0x2e42f7'
,
'0x2e5163'
,
'0x2e3dd1'
,
'0x2e49b7'
,
'0x2e4907'
,
'0x2e4ddb'
,
'0x2e2896'
,
'0x2e2e08'
,
'0x2e35a4'
,
'0x2e2bd2'
,
'0x2e32a2'
,
'0x2e2cf2'
,
'0x2e296d'
,
'0x2e2eb6'
,
'0x2e3391'
,
'0x2e2f9b'
,
'0x2e2ff8'
,
'0x2e2b83'
,
'0x2e3082'
,
'0x2e2ab3'
,
'0x2e333e'
,
'0x2e2ee9'
,
'0x2e2bc5'
,
'0x2e3519'
,
'0x2e3447'
,
'0x2e31a1'
,
'0x2e33fa'
,
'0x2e2bba'
,
'0x2e3623'
,
'0x2e2b95'
,
'0x2e2e99'
,
'0x2e308d'
,
'0x2e33a0'
,
'0x2e3473'
,
'0x2e35ac'
,
'0x2e2b21'
,
'0x2e2980'
,
'0x2e341d'
,
'0x2e31d4'
,
'0x2e32ab'
,
'0x2e30e2'
,
'0x2e289c'
,
'0x2e2acb'
,
'0x2e30f4'
,
'0x2e34f8'
,
'0x2e3176'
,
'0x2e2e5d'
,
'0x2e2cfe'
,
'0x2e2bfb'
,
'0x2e2f15'
,
'0x2e2c6e'
,
'0x2e2ea5'
,
'0x2e305d'
,
'0x2e2f91'
,
'0x2e3267'
,
'0x2e3210'
,
'0x2e324a'
,
'0x2e330f'
,
'0x2e32d9'
,
'0x2e2e78'
,
'0x2e2924'
,
'0x2e34d5'
,
'0x2e2c19'
,
'0x2e3121'
,
'0x2e2907'
,
'0x2e2a75'
,
'0x2e332e'
,
'0x2e2dc9'
,
'0x2e2edc'
,
'0x2e353d'
,
'0x2e2c2f'
,
'0x2e2cd4'
,
'0x2e28e4'
,
'0x2e2b6c'
,
'0x2e3481'
,
'0x2e294b'
,
'0x2e2b40'
,
'0x2e2e83'
,
'0x2e2f4d'
,
'0x2e31f8'
,
'0x2e4df6'
,
'0x2e4177'
,
'0x2e496d'
,
'0x2e37a1'
,
'0x2e3a3a'
,
'0x2e4d76'
,
'0x2e3e38'
,
'0x2e45bc'
,
'0x2e3f86'
,
'0x2e3df5'
,
'0x2e4242'
,
'0x2e3aee'
,
'0x2e5039'
,
'0x2e3ff8'
,
'0x2e4cb9'
,
'0x2e48a1'
,
'0x2e4135'
,
'0x2e3d05'
,
'0x2e4bd9'
,
'0x2e3c0e'
,
'0x2e5133'
,
'0x2e42d7'
,
'0x2e4bff'
,
'0x2e39fe'
,
'0x2e50a8'
,
'0x2e4a2f'
,
'0x2e4e6a'
,
'0x2e43f6'
,
'0x2e401d'
,
'0x2e43a1'
,
'0x2e4b95'
,
'0x2e37d5'
,
'0x2e404d'
,
'0x2e37c6'
,
'0x2e46b3'
,
'0x2e5120'
,
'0x2e5013'
,
'0x2e5075'
,
'0x2e4673'
,
'0x2e45e1'
,
'0x2e3ba2'
,
'0x2e4802'
,
'0x2e481c'
,
'0x2e38d6'
,
'0x2e4f11'
,
'0x2e4494'
,
'0x2e41f1'
,
'0x2e3853'
,
'0x2e504d'
,
'0x2e4529'
,
'0x2e50df'
,
'0x2e3671'
,
'0x2e3968'
,
'0x2e3741'
,
'0x2e4074'
,
'0x2e368e'
,
'0x2e4ffb'
,
'0x2e4c86'
,
'0x2e491f'
,
'0x2e432b'
,
'0x2e3e8c'
,
'0x2e3f97'
,
'0x2e38e5'
,
'0x2e44bc'
,
'0x2e444e'
,
'0x2e3a48'
,
'0x2e39c9'
,
'0x2e46d2'
,
'0x2e3982'
,
'0x2e3eed'
,
'0x2e4682'
,
'0x2e3d7c'
,
'0x2e3eb6'
,
'0x2e3c25'
,
'0x2e4390'
,
'0x2e462c'
,
'0x2e4957'
,
'0x2e4a0c'
,
'0x2e486e'
,
'0x2e493b'
,
'0x2e4479'
,
'0x2e4760'
,
'0x2e4ed5'
,
'0x2e4eb6'
,
'0x2e4d52'
,
'0x2e39a8'
,
'0x2e41bb'
,
'0x2e4e48'
,
'0x2e39b4'
,
'0x2e513e'
,
'0x2e41a4'
,
'0x2e473a'
,
'0x2e4abe'
,
'0x2e47d8'
,
'0x2e4650'
,
'0x2e51b7'
,
'0x2e4367'
,
'0x2e3b75'
,
'0x2e3c63'
,
'0x2e4542'
,
'0x2e487f'
,
'0x2e4b79'
,
'0x2e4ccc'
,
'0x2e3cc8'
,
'0x2e4d28'
,
'0x2e36f1'
,
'0x2e4a7b'
,
'0x2e3cd3'
,
'0x2e3e98'
,
'0x2e4f28'
,
'0x2e3847'
,
'0x2e38ac'
,
'0x2e365c'
,
'0x2e454f'
,
'0x2e3944'
,
'0x2e4105'
,
'0x2e4506'
,
'0x2e4bb6'
,
'0x2e3893'
,
'0x2e4c71'
,
'0x2e3839'
,
'0x2e4f3b'
,
'0x2e3bca'
,
'0x2e3795'
,
'0x2e3b16'
,
'0x2e40c9'
,
'0x2e3d3c'
,
'0x2e3afe'
,
'0x2e5230'
,
'0x2e419c'
]
[
'0x2e1010'
,
'0x2e3634'
,
'0x2e3e1d'
,
'0x2e389c'
,
'0x2e3d9e'
,
'0x2e3b8e'
,
'0x2e37ae'
,
'0x2e3f3a'
,
'0x2e4ee5'
,
'0x2e51ad'
,
'0x2e45f9'
,
'0x2e4e03'
,
'0x2e3c8f'
,
'0x2e4cf1'
,
'0x2e4e96'
,
'0x2e3d49'
,
'0x2e3641'
,
'0x2e4ca8'
,
'0x2e49fd'
,
'0x2e5109'
,
'0x2e4e16'
,
'0x2e382a'
,
'0x2e48f1'
,
'0x2e3ec2'
,
'0x2e4567'
,
'0x2e3a7e'
,
'0x2e4ae0'
,
'0x2e3718'
,
'0x2e402f'
,
'0x2e4ba1'
,
'0x2e4263'
,
'0x2e4441'
,
'0x2e4af2'
,
'0x2e42f7'
,
'0x2e5163'
,
'0x2e3dd1'
,
'0x2e49b7'
,
'0x2e4907'
,
'0x2e4ddb'
,
'0x2e2896'
,
'0x2e2e08'
,
'0x2e35a4'
,
'0x2e2bd2'
,
'0x2e32a2'
,
'0x2e2cf2'
,
'0x2e296d'
,
'0x2e2eb6'
,
'0x2e3391'
,
'0x2e2f9b'
,
'0x2e2ff8'
,
'0x2e2b83'
,
'0x2e3082'
,
'0x2e2ab3'
,
'0x2e333e'
,
'0x2e2ee9'
,
'0x2e2bc5'
,
'0x2e3519'
,
'0x2e3447'
,
'0x2e31a1'
,
'0x2e33fa'
,
'0x2e2bba'
,
'0x2e3623'
,
'0x2e2b95'
,
'0x2e2e99'
,
'0x2e308d'
,
'0x2e33a0'
,
'0x2e3473'
,
'0x2e35ac'
,
'0x2e2b21'
,
'0x2e2980'
,
'0x2e341d'
,
'0x2e31d4'
,
'0x2e32ab'
,
'0x2e30e2'
,
'0x2e289c'
,
'0x2e2acb'
,
'0x2e30f4'
,
'0x2e34f8'
,
'0x2e3176'
,
'0x2e2e5d'
,
'0x2e2cfe'
,
'0x2e2bfb'
,
'0x2e2f15'
,
'0x2e2c6e'
,
'0x2e2ea5'
,
'0x2e305d'
,
'0x2e2f91'
,
'0x2e3267'
,
'0x2e3210'
,
'0x2e324a'
,
'0x2e330f'
,
'0x2e32d9'
,
'0x2e2e78'
,
'0x2e2924'
,
'0x2e34d5'
,
'0x2e2c19'
,
'0x2e3121'
,
'0x2e2907'
,
'0x2e2a75'
,
'0x2e332e'
,
'0x2e2dc9'
,
'0x2e2edc'
,
'0x2e353d'
,
'0x2e2c2f'
,
'0x2e2cd4'
,
'0x2e28e4'
,
'0x2e2b6c'
,
'0x2e3481'
,
'0x2e294b'
,
'0x2e2b40'
,
'0x2e2e83'
,
'0x2e2f4d'
,
'0x2e31f8'
,
'0x2e4df6'
,
'0x2e4177'
,
'0x2e496d'
,
'0x2e37a1'
,
'0x2e3a3a'
,
'0x2e4d76'
,
'0x2e3e38'
,
'0x2e45bc'
,
'0x2e3f86'
,
'0x2e3df5'
,
'0x2e4242'
,
'0x2e3aee'
,
'0x2e5039'
,
'0x2e3ff8'
,
'0x2e4cb9'
,
'0x2e48a1'
,
'0x2e4135'
,
'0x2e3d05'
,
'0x2e4bd9'
,
'0x2e3c0e'
,
'0x2e5133'
,
'0x2e42d7'
,
'0x2e4bff'
,
'0x2e39fe'
,
'0x2e50a8'
,
'0x2e4a2f'
,
'0x2e4e6a'
,
'0x2e43f6'
,
'0x2e401d'
,
'0x2e43a1'
,
'0x2e4b95'
,
'0x2e37d5'
,
'0x2e404d'
,
'0x2e37c6'
,
'0x2e46b3'
,
'0x2e5120'
,
'0x2e5013'
,
'0x2e5075'
,
'0x2e4673'
,
'0x2e45e1'
,
'0x2e3ba2'
,
'0x2e4802'
,
'0x2e481c'
,
'0x2e38d6'
,
'0x2e4f11'
,
'0x2e4494'
,
'0x2e41f1'
,
'0x2e3853'
,
'0x2e504d'
,
'0x2e4529'
,
'0x2e50df'
,
'0x2e3671'
,
'0x2e3968'
,
'0x2e3741'
,
'0x2e4074'
,
'0x2e368e'
,
'0x2e4ffb'
,
'0x2e4c86'
,
'0x2e491f'
,
'0x2e432b'
,
'0x2e3e8c'
,
'0x2e3f97'
,
'0x2e38e5'
,
'0x2e44bc'
,
'0x2e444e'
,
'0x2e3a48'
,
'0x2e39c9'
,
'0x2e46d2'
,
'0x2e3982'
,
'0x2e3eed'
,
'0x2e4682'
,
'0x2e3d7c'
,
'0x2e3eb6'
,
'0x2e3c25'
,
'0x2e4390'
,
'0x2e462c'
,
'0x2e4957'
,
'0x2e4a0c'
,
'0x2e486e'
,
'0x2e493b'
,
'0x2e4479'
,
'0x2e4760'
,
'0x2e4ed5'
,
'0x2e4eb6'
,
'0x2e4d52'
,
'0x2e39a8'
,
'0x2e41bb'
,
'0x2e4e48'
,
'0x2e39b4'
,
'0x2e513e'
,
'0x2e41a4'
,
'0x2e473a'
,
'0x2e4abe'
,
'0x2e47d8'
,
'0x2e4650'
,
'0x2e51b7'
,
'0x2e4367'
,
'0x2e3b75'
,
'0x2e3c63'
,
'0x2e4542'
,
'0x2e487f'
,
'0x2e4b79'
,
'0x2e4ccc'
,
'0x2e3cc8'
,
'0x2e4d28'
,
'0x2e36f1'
,
'0x2e4a7b'
,
'0x2e3cd3'
,
'0x2e3e98'
,
'0x2e4f28'
,
'0x2e3847'
,
'0x2e38ac'
,
'0x2e365c'
,
'0x2e454f'
,
'0x2e3944'
,
'0x2e4105'
,
'0x2e4506'
,
'0x2e4bb6'
,
'0x2e3893'
,
'0x2e4c71'
,
'0x2e3839'
,
'0x2e4f3b'
,
'0x2e3bca'
,
'0x2e3795'
,
'0x2e3b16'
,
'0x2e40c9'
,
'0x2e3d3c'
,
'0x2e3afe'
,
'0x2e5230'
,
'0x2e419c'
]
mu.hook_add(UC_HOOK_MEM_READ,
self
.hook_mem_read)
def
hook_mem_read(
self
, mu, access, address, size, value, data):
if
address >
=
INPUT_ADDRESS
and
address <
=
INPUT_ADDRESS
+
41
:
print
(f
'Read input[{address - INPUT_ADDRESS}] at {hex(mu.reg_read(UC_X86_REG_RIP))}'
)
if
address >
=
KEY_ADDRESS
and
address <
=
KEY_ADDRESS
+
16
:
print
(f
'Read key[{address - KEY_ADDRESS}] at {hex(mu.reg_read(UC_X86_REG_RIP))}'
)
mu.hook_add(UC_HOOK_MEM_READ,
self
.hook_mem_read)
def
hook_mem_read(
self
, mu, access, address, size, value, data):
if
address >
=
INPUT_ADDRESS
and
address <
=
INPUT_ADDRESS
+
41
:
print
(f
'Read input[{address - INPUT_ADDRESS}] at {hex(mu.reg_read(UC_X86_REG_RIP))}'
)
if
address >
=
KEY_ADDRESS
and
address <
=
KEY_ADDRESS
+
16
:
print
(f
'Read key[{address - KEY_ADDRESS}] at {hex(mu.reg_read(UC_X86_REG_RIP))}'
)
Read
input
[
8
] at
0x2e326d
Read
input
[
8
] at
0x2e3214
Read
input
[
8
] at
0x2e3219
Read
input
[
9
] at
0x2e324a
Read
input
[
9
] at
0x2e3254
Read
input
[
9
] at
0x2e325e
Read key[
0
] at
0x2e3a3e
Read
input
[
8
] at
0x2e326d
Read
input
[
8
] at
0x2e3214
Read
input
[
8
] at
0x2e3219
Read
input
[
9
] at
0x2e324a
Read
input
[
9
] at
0x2e3254
Read
input
[
9
] at
0x2e325e
Read key[
0
] at
0x2e3a3e
def
trace(
self
, mu, address, size, data):
disasm
=
self
.md.disasm(mu.mem_read(address, size), address)
for
i
in
disasm:
mnemonic
=
i.mnemonic
if
mnemonic
=
=
'cmp'
or
mnemonic
=
=
'test'
:
print
(f
'Instruction {mnemonic} at {hex(address)}'
)
if
address !
=
self
.except_addr:
self
.traces.append(address)
self
.except_addr
=
address
+
size
def
trace(
self
, mu, address, size, data):
disasm
=
self
.md.disasm(mu.mem_read(address, size), address)
for
i
in
disasm:
mnemonic
=
i.mnemonic
if
mnemonic
=
=
'cmp'
or
mnemonic
=
=
'test'
:
print
(f
'Instruction {mnemonic} at {hex(address)}'
)
if
address !
=
self
.except_addr:
self
.traces.append(address)
self
.except_addr
=
address
+
size
Instruction
cmp
at
0x2e3ca1
Instruction
cmp
at
0x2e4de8
Instruction
cmp
at
0x2e326d
Read
input
[
8
] at
0x2e326d
Instruction
cmp
at
0x2e3214
Read
input
[
8
] at
0x2e3214
Read
input
[
8
] at
0x2e3219
Instruction
cmp
at
0x2e324a
Read
input
[
9
] at
0x2e324a
Instruction
cmp
at
0x2e3254
Read
input
[
9
] at
0x2e3254
Read
input
[
9
] at
0x2e325e
Instruction test at
0x2e4177
Read key[
0
] at
0x2e3a3e
Instruction
cmp
at
0x2e38e7
Instruction
cmp
at
0x2e3ca1
Instruction
cmp
at
0x2e4de8
Instruction
cmp
at
0x2e326d
Read
input
[
8
] at
0x2e326d
Instruction
cmp
at
0x2e3214
Read
input
[
8
] at
0x2e3214
Read
input
[
8
] at
0x2e3219
Instruction
cmp
at
0x2e324a
Read
input
[
9
] at
0x2e324a
Instruction
cmp
at
0x2e3254
Read
input
[
9
] at
0x2e3254
Read
input
[
9
] at
0x2e325e
Instruction test at
0x2e4177
Read key[
0
] at
0x2e3a3e
Instruction
cmp
at
0x2e38e7
def
trace(
self
, mu, address, size, data):
if
address !
=
self
.except_addr:
self
.traces.append(address)
self
.except_addr
=
address
+
size
if
address
=
=
0x2E38EF
:
self
.hit
+
=
1
if
self
.hit
=
=
self
.except_hit:
self
.success
=
True
mu.emu_stop()
def
trace(
self
, mu, address, size, data):
if
address !
=
self
.except_addr:
self
.traces.append(address)
self
.except_addr
=
address
+
size
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-9-22 10:44
被34r7hm4n编辑
,原因: