学习纪录
动态分析技术实践
第一个小程序
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
::hInstance = hInstance;
DialogBoxParamA(hInstance, (LPCSTR)0x65, 0, DialogFunc, 0);
return 0;
}
重要代码
v5 = GetDlgItemTextA(hWnd, 0x6E, &user, 0x51);// 调用GetDlgItemTextA 函数读入用户名
GetDlgItemTextA(hWnd, 1000, &pass, 101); // 调用GetDlgItemTextA 函数读入序列号
if ( user && v5 >= 5 ) // 名字要大于4
{
if ( check(&pass, &user, v5) ) // 验证用户名和序列号
{
....
BOOL __cdecl check(LPCSTR lpString1, LPSTR a2, int a3)
{
int v3; // ecx
int v4; // esi
signed int i; // eax
v3 = 3;
v4 = 0;
//这里将用户名进行一个计算
for ( i = 0; v3 < a3; ++i )
{
if ( i > 7 )
i = 0;
v4 += (unsigned __int8)byte_405030[i] * (unsigned __int8)a2[v3++];
}
wsprintfA(a2, aLd, v4);
return lstrcmpA(lpString1, a2) == 0;
}
text:004011E4 push eax ; lpString1
.text:004011E5 call check
.text:004011EA mov edi, ds:GetDlgItem
.text:004011F0 add esp, 0Ch
.text:004011F3 test eax, eax ;eax等于1 则成功
.text:004011F5 jz short loc_40122E; eax等于0 则跳转
.text:004011F7 lea ecx, [esp+100h+String2]
.text:004011FB push ecx ; lpString2
.text:004011FC push offset String1 ; lpString1
.text:00401201 call ds:lstrcpyA
写出注册机
key = [0xc,0xa,0x13,0x9,0xc,0xb,0xa,0x8]
name = input(str)
flag = 0
j = 2
for i in range (len(name)-3):
if i>7:
i=0
flag =flag + key[i]*((ord(name[j])))
j = j+1
print flag
注意一下 循环的次数
爆破法:
直接patch 它,将跳转代码nop掉
动态直接看内存