这个check就是个按钮,现在用visual studio提供的工具看看这个按钮id
找到check按钮id是1
AFX_MSGMAP_ENTRY 按钮;按钮。nMessage = WM_COMMAND ; 按钮。nCode = BN_CLICKED ; 按钮。nID = 1 ; 按钮。nLastID = 1 ; 按钮。nSig = AfxSigCmd_v ; 按钮。pfn =未知;
等价替换后
btn.nMessage=0x0111; btn.nCode=0; btn.nID=1; btn.nLastID=1; btn.nSig=AfxSigCmd_v; btn.pfn=CMFCApplication3Dlg::未知;
btn的内存呈现形式为
nMessage,nCode,nID,nLastID,nSig,pfn
可以不用管nSig,pfn的值,只用搜索前四项就够了,等价替换为
0x0111, 0, 1,1,nSig,pfn 等价替换为
11 01 00 00, 00 00 00 00, 01 00 00 00, 01 00 00 00 ,nSig,pfn 等价替换为
11 01 00 00 00 00 00 00 01 00 00 00 01 00 00 00
找到按钮事件地址 795E7980
#include #include class myclass
{ public:
virtual void func1()
{
}
virtual void func2()
{
}
}; int main ( )
{
printf ( "MYACLS::myvirfunc1()地址=%p\n" , & myclass :: func1 ) ; //打印的是vcall函数 printf ( "MYACLS::myvirfunc2()地址=%p\n" , & myclass :: func2 ) ;
myclass * pmyobj = new myclass ( ) ;
返回 1 ;
}
#### 而myvirfunc1 myvirfunc2函数真正的地址为
现在00FB1084与00FB1088代码组合
是不是和地址795E7980代码很相似
调整这个指针到真正的虚函数中
ida打开该程序跳转00401512
text:00401518 mov [ebp+var_20], ecx
.text:0040151B mov ax, word_40315C
.text:00401521 mov word ptr [ebp+String], ax
.text:00401525 xor ecx, ecx
.text:00401527 mov [ebp+var_A], ecx
.text:0040152A mov [ebp+var_6], ecx
.text:0040152D mov edx, dword_403020
.text:00401533 mov dword ptr [ebp+String2], edx
.text:00401536 mov eax, dword_403024 .text:0040153B mov [ebp+var_18], eax
.text:0040153E mov cx, word_403028
.text:00401545 mov [ebp+var_14], cx
var_20看前后使用是 用来this指针的不用管
var_A和var_6都被初始化为0,上下文都没有使用,说明是数组
String 只初始化了2个字节,加上var_A和var_6,String是10个字节
String2 和var_18,var_14地址相连,var_18,var_14上下文都没有使用,说明是数组 var_14只初始化了2个字节,加上String2和var_18,String2是10个字节 dword_403020 值为4472423C,dword_403024值为426F532D,word_403028值为003E换成asci码为
代码为
CHAR String[10]={0};//因为汇编代码中都数组中的值被初始化为0了,所以写成String[10]={0}
CHAR String2[10]="";
.text:00401549 push 0Ah ; int
.text:0040154B lea edx, [ebp+String]
.text:0040154E push edx ; char * .text:0040154F push 3E8h ; int
.text:00401554 mov ecx, [ebp+var_20] ; this
.text:00401557 call ?GetDlgItemTextA@CWnd@@QBEHHPADH@Z ; CWnd::GetDlgItemTex
.text:0040155C lea eax, [ebp+String]
.text:0040155F push eax ; lpString
.text:00401560 call ds:lstrlenA
.text:00401566 mov [ebp+var_10], eax
.text:00401569 cmp [ebp+var_10], 1
.text:0040156D jnb short loc_401585
push的是10,调用的函数是intGetDlgItemText(intnID**,LPTSTRlpStr,intnMaxCount),说明数组 大就是10, var_10=lstrlenA函数的返回值, 后比较的后的跳转指令是jnb 说明var_10是无符号的
代码为
GetDlgItemTextA(1000, String, 10); unsigned int var_10; var_10 = lstrlenA(String); if ( var_10<1)
.text:0040156F push 40h ; '@' ; unsigned int
.text:00401571 push offset aCrackme ; "CrackMe"
.text:00401576 push offset aEnterRegistrat ; "Enter Registration Number"
.text:0040157B mov ecx, [ebp+var_20] ; this
.text:0040157E call ?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char
.text:00401583 jmp short loc_4015C1
.text:00401585 ; --------------------------------------------------------------------------- .text:00401585
.text:00401585 loc_401585: ; CODE XREF: sub_401512+5B↑j
.text:00401585 lea ecx, [ebp+String2]
.text:00401588 push ecx ; lpString2 .text:00401589 lea edx, [ebp+String]
.text:0040158C push edx ; lpString1
.text:0040158D call ds:lstrcmpA
.text:00401593 test eax, eax
.text:00401595 jnz short loc_4015AD
.text:00401597 push 40h ; '@' ; unsigned int
.text:00401599 push offset aCrackme_0 ; "CrackMe"
.text:0040159E push offset aCorrectWayToGo ; "Correct way to go!!"
.text:004015A3 mov ecx, [ebp+var_20] ; this
.text:004015A6 call ?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char
.text:004015AB jmp short loc_4015C1
.text:004015AD ; --------------------------------------------------------------------------- .text:004015AD
.text:004015AD loc_4015AD: ; CODE XREF: sub_401512+83↑j
.text:004015AD push 40h ; '@' ; unsigned int
.text:004015AF push offset aCrackme_1 ; "CrackMe"
.text:004015B4 push offset aIncorrectTryAg ; "Incorrect try again!!"
.text:004015B9 mov ecx, [ebp+var_20] ; this
.text:004015BC call ?MessageBoxA@CWnd@@QAEHPBD0I@Z ; CWnd::MessageBoxA(char .text:004015C1
.text:004015C1 loc_4015C1: ; CODE XREF: sub_401512+71↑j
.text:004015C1 ; sub_401512+99↑j
.text:004015C1 mov esp, ebp
.text:004015C3 pop ebp
.text:004015C4 retn
.text:004015C4 sub_401512 endp
汇编结构来看感觉是 if, elseif, else结构代码为
MessageBoxA("Enter Registration Number", "CrackMe", 0x40u); else if ( lstrcmpA(String, String2) )
MessageBoxA("Incorrect try again!!", "CrackMe", 0x40u);
else
MessageBoxA("Correct way to go!!", "CrackMe", 0x40u);
CHAR String2[10]=""; unsigned int var_10;
CHAR String[10]={0};//因为汇编代码中都数组中的值被初始化为0了,所以写成String[10]={0}
GetDlgItemTextA(1000, String, 10); var_10 = lstrlenA(String); if ( var_10<1)
MessageBoxA("Enter Registration Number", "CrackMe", 0x40u); else if ( lstrcmpA(String, String2) )
MessageBoxA("Incorrect try again!!", "CrackMe", 0x40u);
else
MessageBoxA("Correct way to go!!", "CrackMe", 0x40u);
选择用Release编译,第二因为该crackme是用ebp寻找的局部变量,说明没有开 o2优化编译,我个人就选择的无优化编译,最后生成的二进制和原版还有略有差异