动态调试

exe文件的动调

常规操作查壳后丢进Ida分析

思路

image
在开头是一个start,点进去之后发现几个初始化,找不到对解题有帮助的代码,应该就是有去符号表几个常用的手段。
shift+f12看一下字符串
image
这里就很明显了,在right 那里就是主函数的位置
交叉引用,直接追踪到函数的位置
image
可以发现在j_memcmp处就是对比输入输出的地方,但是静态分析点进去啥也没有,所有就应该是这里有hook该函数了
动态调试看一下
image
F7步入这个函数之后就直接进入了vmp段,所有不难看出来具有一些反调试的手段
看看导入部分
image
直接看Isdebuggerpresent,想办法绕过
后续还有if的判断语句,猜测可能就是一个smc段,同样利用动态调试进行绕过
image
后面就是操作修复环节
image
修改标识位,绕过最开始的反调试
image
直接来到了sub_41D000,可以判断就是对这一段进行了加密
image
直接重新分析然后P
得到原本的函数
image
这个函数就是对应IAT hook的流程,下面的sub_41D250就是真正的memcmp函数
`__int64 __cdecl sub_41D250(char *Str)
{
__int64 v1; // rax
__int64 v3; // [esp-8h] [ebp-24Ch]
int j; // [esp+D0h] [ebp-174h]
size_t i; // [esp+F4h] [ebp-150h]
char *v6; // [esp+100h] [ebp-144h]
int v7; // [esp+124h] [ebp-120h] BYREF
int v8; // [esp+128h] [ebp-11Ch]
int v9; // [esp+12Ch] [ebp-118h]
int v10; // [esp+130h] [ebp-114h]
_BYTE v11[260]; // [esp+13Ch] [ebp-108h] BYREF
int savedregs; // [esp+244h] [ebp+0h] BYREF

sub_4114D8(&unk_4250F3);
v11[0] = -7;
v11[1] = 77;
v11[2] = 43;
v11[3] = -68;
v11[4] = 19;
v11[5] = -35;
v11[6] = 19;
v11[7] = 98;
v11[8] = -55;
v11[9] = -4;
v11[10] = -1;
v11[11] = -119;
v11[12] = 125;
v11[13] = 79;
v11[14] = -55;
v11[15] = 15;
v11[16] = 99;
v11[17] = 29;
v11[18] = 109;
v11[19] = 82;
v11[20] = 80;
v11[21] = -3;
v11[22] = 65;
v11[23] = -29;
v11[24] = 51;
v11[25] = 118;
v11[26] = 40;
v11[27] = -105;
v11[28] = 56;
v11[29] = 54;
v11[30] = -7;
v11[31] = 107;
v11[32] = -112;
v11[33] = 57;
v11[34] = 20;
v11[35] = -125;
v11[36] = 44;
v11[37] = -30;
v11[38] = 44;
v11[39] = 31;
memset(&v11[40], 0, 216);
v7 = 0;
v8 = 0;
v9 = 0;
v10 = 0;
if ( j_strlen(Str) == 40 )
{
v6 = Str + 4;
v7 = *(_DWORD *)Str;
v8 = *((_DWORD *)Str + 1);
sub_411541(&v7, &unk_422100);
*(_DWORD *)Str = v7;
*((_DWORD *)Str + 1) = v8;
for ( i = 2; i < j_strlen(Str) >> 2; i += 2 )
{
sub_411541(&v7, &unk_422100);
*(_DWORD *)Str = v7;
*(_DWORD *)v6 = v8;
*(_DWORD *)&Str[4 * i] ^= *(_DWORD *)Str;
*(_DWORD *)&Str[4 * i + 4] ^= *(_DWORD *)v6;
}
for ( j = 0; j < 40; ++j )
{
HIDWORD(v1) = j;
if ( Str[j] != v11[j] )
{
LODWORD(v1) = 1;
goto LABEL_12;
}
}
LODWORD(v1) = 0;
}
else
{
LODWORD(v1) = 1;
}
LABEL_12:
v3 = v1;
sub_41130C(&savedregs, &unk_41D5CC);
return v3;
}`

exp

发现就是一个魔改的tea加密,然后key段在前面
image
详细的exp就网上找了一个
`from struct import unpack, pack
enc = [-7,77,43,-68,19,-35,19,98,-55,-4,-1,-119,125,79,-55,15,99,29,109,82,80,-3,65,-29,51,118,40,-105,56,54,-7,107,-112,57,20,-125,44,-30,44,31]

for i in range(len(enc)):
enc[i] &= 0xff

print(unpack('<10I', bytes(enc)))

from struct import unpack, pack

enc = [3156954617, 1645468947, 2315254985, 264851325, 1382882659, 3812752720, 2536011315, 1811494456, 2199140752, 523035180]
key = [0x12345678, 0x09101112, 0x13141516, 0x15161718]

最后两个直接xor enc[0]和enc[1]即可

print(pack('<I', enc[8]^enc[0]).decode()+pack('<I', enc[9]^enc[1]).decode())

for i in range(len(enc)//2-2, 0, -1):
prev = enc[0]
next = enc[1]
sum = (-0x61C88647 * 16) & 0xffffffff
for round in range(16):
sum += 0x61C88647
sum &= 0xffffffff
next -= (key[3] + (prev >> 5)) ^ (sum + prev) ^ (key[2] + 16 * prev)
next &= 0xffffffff
prev -= (key[1] + (next >> 5)) ^ (sum + next) ^ (key[0] + 16 * next)
prev &= 0xffffffff
enc[0] = prev
enc[1] = next
print(pack('<I', enc[2i]^prev).decode()+pack('<I', enc[2i+1]^next).decode())

最后enc[0]和enc[1]还要进行两次tea解密

for i in range(2):
prev = enc[0]
next = enc[1]
sum = (-0x61C88647 * 16) & 0xffffffff
for round in range(16):
sum += 0x61C88647
sum &= 0xffffffff
next -= (key[3] + (prev >> 5)) ^ (sum + prev) ^ (key[2] + 16 * prev)
next &= 0xffffffff
prev -= (key[1] + (next >> 5)) ^ (sum + next) ^ (key[0] + 16 * next)
prev &= 0xffffffff
enc[0] = prev
enc[1] = next

print(pack('<I', enc[0]).decode()+pack('<I', enc[1]).decode())

DASCTF{I4TH0ok_I5S0ooFunny_Isnotit?????}`

posted @ 2026-01-25 22:30  Aques  阅读(1)  评论(0)    收藏  举报