# 180822 逆向-网鼎杯（2-1）

## Reverse

### martricks

main函数中接收输入以后将input和一个字符串异或一下存入savedregs中

from z3 import *
t1 = [115, 111, 109, 101, 32, 108, 101, 103, 101, 110, 100, 115, 32, 114, 32, 116, 111, 108, 100, 44, 32, 115, 111, 109, 101, 32, 116, 117, 114, 110, 32, 116, 111, 32, 100, 117, 115, 116, 32, 111, 114, 32, 116, 111, 32, 103, 111, 108, 100]
t2 = [170, 122, 36, 10, 168, 188, 60, 252, 130, 75, 81, 82, 94, 28, 130, 31, 121, 186, 181, 227, 67, 4, 253, 172, 16, 181, 99, 189, 141, 231, 53, 217, 211, 232, 66, 109, 113, 90, 9, 84, 233, 159, 76, 220, 162, 175, 17, 135, 148]
flag = [BitVec("flag%d"%i, 8) for i in range(49)]
m1 = [0 for i in range(49)]
m2 = [0 for i in range(49)]

i_23 = 23
for i in range(49):
m1[i_23] = flag[i]^i_23
m2[i] = t1[i_23]^i
i_23 = (i_23+13)%49
a = 3
b = 4
c = 5
d = 41
s = Solver()
for i in range(7):
for j in range(7):
sum = 0
for k in range(7):
sum += m2[7*c+b]*m1[7*a+c]
c = (c+5)%7
# print(sum)
s.add(sum==t2[d]^d)
d = (d+31)%49
b = (b+4)%7
a = (a+3)%7
c = (s.check())
f = ""
if(c==sat):
m=s.model()
# print("flag",end='\n')
for i in range(49):
f += (chr(m[flag[i]].as_long()))
print(f)

### give_a_try

GUI程序就不能直接跟着main函数走，而是要找到按钮的点击函数

CreateDialogParamA(dword_404060, 1000, 0, sub_401223, 0);

if ( (unsigned __int16)a3 == 1001 )
{
GetDlgItemTextA(a1, 1002, &Str, 255);
sub_401103(&Str);
}

pizza:004020CA                 call    loc_4020D0
pizza:004020CA ; ---------------------------------------------------------------------------
pizza:004020CF                 db 5
pizza:004020D0 ; ---------------------------------------------------------------------------
pizza:004020D0
pizza:004020D0 loc_4020D0:                             ; CODE XREF: pizza:004020CA↑j
pizza:004020D0                 add     dword ptr [esp], 6
pizza:004020D4                 retn
pizza:004020D5 ; ---------------------------------------------------------------------------
pizza:004020D5                 cmp     dword_40406C, 0

call到4020d0后，会在栈中压入一个ret address指向4020ca–下一条指令的地址

#include <idc.idc>

static matchBytes(StartAddr, Match)
{
auto Len, i, PatSub, SrcSub;
Len = strlen(Match);

while (i < Len)
{
PatSub = substr(Match, i, i+1);
SrcSub = form("%02X", Byte(StartAddr));
SrcSub = substr(SrcSub, i % 2, (i % 2) + 1);

if (PatSub != "?" && PatSub != SrcSub)
{
return 0;
}

if (i % 2 == 1)
{
StartAddr++;
}
i++;
}

return 1;
}

static main()
{
auto Addr, Start, End, Condition, junk_len, i;

Start = 0x402000;
End = 0x4020f4;
Condition = "E801000000??83042406C3";
junk_len = 11;

for (Addr = Start; Addr < End; Addr++)
{
if (matchBytes(Addr, Condition))
{
for (i = 0; i < junk_len; i++)
{
PatchByte(Addr, 0x90);
MakeCode(Addr);
Addr++;
}
}

}

AnalyzeArea(Start, End);
Message("Clear Fake-Jmp Opcode Ok ");
} 

1. NtSetInformationThread这个函数，当第三个参数为0x11（ThreadHideFromDebugger）时，可以去掉所有调试器
2. NtQueryInformationProcess通过第三个参数0x7，可以返回调试端口到某个变量中。之后可以通过判断该变量是否为0来反调。


#include <stdio.h>
#include <stdlib.h>
int cal(long long ori)
{
int i;
unsigned long long b=ori;
for(i=0;i<16;i++)
{
//printf("%x\n", b);
b = (b * b)%0xFAC96621;
}
return (ori*b)%0xFAC96621;
}
int t[] = {0x63b25af1, 0xc5659ba5, 0x4c7a3c33, 0xe4e4267, 0xb611769b, 0x3de6438c, 0x84dba61f, 0xa97497e6, 0x650f0fb3, 0x84eb507c, 0xd38cd24c, 0xe7b912e0, 0x7976cd4f, 0x84100010, 0x7fd66745, 0x711d4dbf, 0x5402a7e5, 0xa3334351, 0x1ee41bf8, 0x22822ebe, 0xdf5cee48, 0xa8180d59, 0x1576dedc, 0xf0d62b3b, 0x32ac1f6e, 0x9364a640, 0xc282dd35, 0x14c5fc2e, 0xa765e438, 0x7fcf345a, 0x59032bad, 0x9a5600be, 0x5f472dc5, 0x5dde0d84, 0x8df94ed5, 0xbdf826a6, 0x515a737a, 0x4248589e, 0x38a96c20, 0xcc7f61d9, 0x2638c417, 0xd9beb996};

int main()
{
int i, seed;
int r;
char ch;
//3681
/*for(seed=0;seed<=5292;seed++)
{
srand(seed^0x31333359);
r = cal('f'*rand());
//printf("%x\n", r);

if(r==0x63B25AF1){
printf("%d\n", seed);
printf("%x\n", cal('l'*rand()));
break;
}
}
*/
srand(3681^0x31333359);
for(i=0;i<42;i++)
{
r = rand();
//printf("%x\n", r);
for(ch=32;ch<127;ch++)
{
if(cal(ch*r)==t[i])
{
printf("%c", ch);
break;
}
}
if(ch==127){printf("error");break;}

}

return 0;
}



• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120