这是我收藏的提高反汇编能力!
小甲鱼用了一个通宵的时间来编写和调试程序,大家有可能不理解的地方也做了详细注释,谨以此献给喜欢鱼C,热爱编程的朋友们!
仅希望不喜的朋友勿喷,喜欢的朋友耐心学习,回复的朋友注意论坛环境,不要回复一堆毫无意义标点符号!
用这种方法写程序,将其编译链接后的可执行文件用IDA等工具将其反汇编后,两者基本保持一致。掌握这种写法,可以加深对逆向的反应和思考能力,适合平时锻炼提高逆向能力!
程序功能如图:
http://bbs.fishc.com/forum.php?mod=attachment&aid=NDc0OHw2MDFhZGYyNHwxNDA4ODU5ODQ0fDI0NTcwMnwxODMzNw%3D%3D&noupdate=yes
代码及详细注释:
本帖隐藏的内容
[*]
[*];>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[*]; by 小甲鱼, http://www.fishc.com
[*];>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[*]; 功能:实现与反汇编同样语法的汇编编程,有点纠结,但非常有利于锻炼逆向思维!
[*];>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[*] .386
[*] .model flat,stdcall
[*] option casemap:none
[*]
[*]include windows.inc
[*]include user32.inc
[*]include kernel32.inc
[*]includelib user32.lib
[*]includelib kernel32.lib
[*]
[*] .data
[*]hIcon dd0
[*]hWnd dd0
[*]hDc dd0
[*]winX dd0
[*]winY dd0
[*]wWidth dd0
[*]wHeight dd0
[*]stPs PAINTSTRUCT <0>
[*]stRect RECT <0>
[*]wc WNDCLASSEX<0> ; wc定义为WNDCALSSEX结构,并用零填充
[*]msg MSG <0> ; 用于存放消息
[*]szClassName db'MyClass', 0
[*]szCaption db'欢迎来到鱼C工作室', 0
[*]szMessage db'学习编程最好的地方 -- 鱼C工作室: www.fishc.com', 0
[*]
[*] .code
[*]main:
[*] push ebp ; 保存上一个程序的ebp
[*] mov ebp, esp ; ebp == esp,ebp主要用于后边的参数和变量的索引
[*]
[*];------------------------------------------------------------------
[*];......................... 初始化程序 .............................
[*];------------------------------------------------------------------
[*] push 1000 ; 图标的ID
[*] push DWORD PTR ; 就是在调用main函数前压入的参数,为本模块的句柄
[*] call LoadIcon
[*] mov hIcon, eax
[*]
[*] mov wc.cbSize, sizeof WNDCLASSEX
[*] mov wc.style, CS_BYTEALIGNWINDOW
[*] mov wc.lpfnWndProc, offset WndProc
[*] mov wc.cbClsExtra, NULL
[*] mov wc.cbWndExtra, NULL
[*] mov eax, ; 就是在调用main函数前压入的参数,为本模块的句柄
[*] mov wc.hInstance, eax
[*] mov wc.hbrBackground, COLOR_WINDOW+1
[*] mov wc.lpszMenuName, NULL
[*] mov wc.lpszClassName, offset szClassName
[*]
[*] push hIcon
[*] pop eax ; 经典做法,相当于mov eax, hIcon
[*] mov wc.hIcon, eax
[*]
[*] push IDC_ARROW
[*] push NULL
[*] call LoadCursor
[*] mov wc.hCursor, eax
[*]
[*] push hIcon
[*] pop eax
[*] mov wc.hIconSm, eax
[*]
[*] push offset wc
[*] call RegisterClassEx ; 注册窗口
[*]
[*] mov wWidth, 600 ; 窗口宽度
[*] mov wHeight, 450 ; 窗口高度
[*] mov winX, 50
[*] mov winY, 50
[*]
[*];------------------------------------------------------------------
[*];........................... 创建窗口 .............................
[*];------------------------------------------------------------------
[*] push NULL
[*] push DWORD PTR ; 还记得吧,本模块句柄
[*] push NULL ; 菜单句柄,这里不需要,所以木有
[*] push NULL ; 父窗口句柄,这里木有,所以没有
[*] push wHeight ; 高度
[*] push wWidth ; 宽度
[*] push winY ; 左上角y值
[*] push winX ; 左上角x值
[*] push WS_OVERLAPPEDWINDOW ; 窗口风格
[*] push offset szCaption ; 标题
[*] push offset szClassName ; 类名
[*] push WS_EX_LEFT ; 扩展窗口风格
[*] call CreateWindowEx ; 上边的都是这个函数的参数,注意入栈是从右到左
[*] mov hWnd, eax
[*]
[*] push SW_SHOWNORMAL
[*] push hWnd
[*] call ShowWindow ; 显示窗口
[*]
[*] push hWnd
[*] call UpdateWindow ; 更新窗口
[*]
[*];------------------------------------------------------------------
[*];........................... 消息循环 .............................
[*];------------------------------------------------------------------
[*]msgLoop:
[*] push 0
[*] push 0
[*] push NULL
[*] push offset msg
[*] call GetMessage ; 获取消息
[*]
[*] cmp eax, 0
[*] je exitLoop ; 如果返回值为0,则退出循环,准备结束程序
[*]
[*] push offset msg
[*] call TranslateMessage ; 转发消息
[*]
[*] push offset msg
[*] call DispatchMessage ; 分派消息
[*]
[*] jmp msgLoop
[*]
[*]exitLoop:
[*] mov esp, ebp ; 恢复堆栈
[*] pop ebp ; 恢复上一个程序的ebp
[*] ret ; 返回
[*]
[*];------------------------------------------------------------------
[*];........................... 窗口过程 .............................
[*];------------------------------------------------------------------
[*]WndProc:
[*] push ebp
[*] mov ebp, esp
[*]
[*]; 小甲鱼再啰嗦下!WndProc proc hWin, uMsg, wPrarm, lParam
[*]; | | | |
[*]; 他们分别用ebp的索引值是: ebp+8 ebp+12 ebp+16ebp+20
[*] cmp DWORD PTR , WM_PAINT ; 判断是否绘制窗口消息
[*] jne @F
[*]
[*] push offset stPs
[*] push ; hWin入栈
[*] call BeginPaint
[*] mov hDc, eax
[*]
[*] push offset stRect
[*] push
[*] call GetClientRect
[*]
[*] push DT_SINGLELINE or DT_CENTER or DT_VCENTER
[*] push offset stRect
[*] push -1
[*] push offset szMessage
[*] push hDc
[*] call DrawText
[*]
[*] push offset stPs
[*] push
[*] call EndPaint ; 擦屁股,释放资源
[*]
[*]@@:
[*] cmp DWORD PTR , WM_CLOSE ; 判断是不是获得关闭的消息
[*] jne @F
[*]
[*] push NULL
[*] call PostQuitMessage
[*]
[*]@@:
[*] push DWORD PTR ; lParam
[*] push DWORD PTR ; wParam
[*] push DWORD PTR ; uMsg
[*] push DWORD PTR ; hWin
[*] call DefWindowProc ; 把我们不关注的消息都让默认函数来处理
[*]
[*] mov esp, ebp
[*] pop ebp
[*] ret
[*]
[*]start:
[*] push NULL
[*] call GetModuleHandle ; 获取本模块句柄,注意现在我们不用invoke,我们时刻要保持反汇编写法
[*]
[*] push eax ; eax保存着拿到的模块句柄,并作为main函数的参数入栈
[*] call main
[*]
[*] push 0
[*] call ExitProcess ; 退出程序
[*]
[*] end start
[*]
复制代码
以下是用IDA逆向后的反汇编程序,请鱼油们注意比较,两者基本保持一致。
[*]
[*].text:00401000 ; int __cdecl sub_401000(HINSTANCE hInstance)
[*].text:00401000 sub_401000 proc near ; CODE XREF: start+8p
[*].text:00401000
[*].text:00401000 hInstance = dword ptr8
[*].text:00401000
[*].text:00401000 push ebp
[*].text:00401001 mov ebp, esp
[*].text:00401003 push 3E8h ; lpIconName
[*].text:00401008 push ; hInstance
[*].text:0040100B call LoadIconA
[*].text:00401010 mov dword_403000, eax
[*].text:00401015 mov stru_40306C.cbSize, 30h
[*].text:0040101F mov stru_40306C.style, 2000h
[*].text:00401029 mov stru_40306C.lpfnWndProc, offset sub_40114B
[*].text:00401033 mov stru_40306C.cbClsExtra, 0
[*].text:0040103D mov stru_40306C.cbWndExtra, 0
[*].text:00401047 mov eax,
[*].text:0040104A mov stru_40306C.hInstance, eax
[*].text:0040104F mov stru_40306C.hbrBackground, 6
[*].text:00401059 mov stru_40306C.lpszMenuName, 0
[*].text:00401063 mov stru_40306C.lpszClassName, offset ClassName ; "MyClass"
[*].text:0040106D push dword_403000
[*].text:00401073 pop eax
[*].text:00401074 mov stru_40306C.hIcon, eax
[*].text:00401079 push 7F00h ; lpCursorName
[*].text:0040107E push 0 ; hInstance
[*].text:00401080 call LoadCursorA
[*].text:00401085 mov stru_40306C.hCursor, eax
[*].text:0040108A push dword_403000
[*].text:00401090 pop eax
[*].text:00401091 mov stru_40306C.hIconSm, eax
[*].text:00401096 push offset stru_40306C ; WNDCLASSEXA *
[*].text:0040109B call RegisterClassExA
[*].text:004010A0 mov nWidth, 258h
[*].text:004010AA mov nHeight, 1C2h
[*].text:004010B4 mov X, 32h
[*].text:004010BE mov Y, 32h
[*].text:004010C8 push 0 ; lpParam
[*].text:004010CA push ; hInstance
[*].text:004010CD push 0 ; hMenu
[*].text:004010CF push 0 ; hWndParent
[*].text:004010D1 push nHeight ; nHeight
[*].text:004010D7 push nWidth ; nWidth
[*].text:004010DD push Y ; Y
[*].text:004010E3 push X ; X
[*].text:004010E9 push 0CF0000h ; dwStyle
[*].text:004010EE push offset WindowName ; "欢迎来到鱼C工?
[*].text:004010F3 push offset ClassName ; "MyClass"
[*].text:004010F8 push 0 ; dwExStyle
[*].text:004010FA call CreateWindowExA
[*].text:004010FF mov hWnd, eax
[*].text:00401104 push 1 ; nCmdShow
[*].text:00401106 push hWnd ; hWnd
[*].text:0040110C call ShowWindow
[*].text:00401111 push hWnd ; hWnd
[*].text:00401117 call UpdateWindow
[*].text:0040111C
[*].text:0040111C loc_40111C: ; CODE XREF: sub_401000+145j
[*].text:0040111C push 0 ; wMsgFilterMax
[*].text:0040111E push 0 ; wMsgFilterMin
[*].text:00401120 push 0 ; hWnd
[*].text:00401122 push offset Msg ; lpMsg
[*].text:00401127 call GetMessageA
[*].text:0040112C cmp eax, 0
[*].text:0040112F jz short loc_401147
[*].text:00401131 push offset Msg ; lpMsg
[*].text:00401136 call TranslateMessage
[*].text:0040113B push offset Msg ; lpMsg
[*].text:00401140 call DispatchMessageA
[*].text:00401145 jmp short loc_40111C
[*].text:00401147 ; ---------------------------------------------------------------------------
[*].text:00401147
[*].text:00401147 loc_401147: ; CODE XREF: sub_401000+12Fj
[*].text:00401147 mov esp, ebp
[*].text:00401149 pop ebp
[*].text:0040114A retn
[*].text:0040114A sub_401000 endp
[*].text:0040114A
[*].text:0040114B
[*].text:0040114B ; =============== S U B R O U T I N E =======================================
[*].text:0040114B
[*].text:0040114B ; Attributes: bp-based frame
[*].text:0040114B
[*].text:0040114B ; int __cdecl sub_40114B(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
[*].text:0040114B sub_40114B proc near ; DATA XREF: sub_401000+29o
[*].text:0040114B
[*].text:0040114B hWnd = dword ptr8
[*].text:0040114B Msg = dword ptr0Ch
[*].text:0040114B wParam = dword ptr10h
[*].text:0040114B lParam = dword ptr14h
[*].text:0040114B
[*].text:0040114B push ebp
[*].text:0040114C mov ebp, esp
[*].text:0040114E cmp , 0Fh
[*].text:00401152 jnz short loc_401199
[*].text:00401154 push offset Paint ; lpPaint
[*].text:00401159 push ; hWnd
[*].text:0040115C call BeginPaint
[*].text:00401161 mov hdc, eax
[*].text:00401166 push offset Rect ; lpRect
[*].text:0040116B push ; hWnd
[*].text:0040116E call GetClientRect
[*].text:00401173 push 25h ; format
[*].text:00401175 push offset Rect ; lprc
[*].text:0040117A push 0FFFFFFFFh ; cchText
[*].text:0040117C push offset chText ; "学习编程最好的地方 -- 鱼C工?
[*].text:00401181 push hdc ; hdc
[*].text:00401187 call DrawTextA
[*].text:0040118C push offset Paint ; lpPaint
[*].text:00401191 push ; hWnd
[*].text:00401194 call EndPaint
[*].text:00401199
[*].text:00401199 loc_401199: ; CODE XREF: sub_40114B+7j
[*].text:00401199 cmp , 10h
[*].text:0040119D jnz short loc_4011A6
[*].text:0040119F push 0 ; nExitCode
[*].text:004011A1 call PostQuitMessage
[*].text:004011A6
[*].text:004011A6 loc_4011A6: ; CODE XREF: sub_40114B+52j
[*].text:004011A6 push ; lParam
[*].text:004011A9 push ; wParam
[*].text:004011AC push ; Msg
[*].text:004011AF push ; hWnd
[*].text:004011B2 call DefWindowProcA
[*].text:004011B7 mov esp, ebp
[*].text:004011B9 pop ebp
[*].text:004011BA retn
[*].text:004011BA sub_40114B endp
[*].text:004011BA
[*]
复制代码
厉害 谢谢分享
页:
[1]