【文章标题】: PE文件添加区段[逆向分析+asm代码实现]
【文章作者】: eASYSCt
【作者主页】: http://blog.sina.com.cn/77muyulong
【软件名称】: zeroadd
【下载地址】: 自己搜索下载
【加壳方式】: 无壳
【保护方式】: 无
【编写语言】: 汇编
【使用工具】: ODB
【软件介绍】: 一款为PE文件添加区段的小工具
【作者声明】: 只是为学习原理 并无其他目的 大侠指教~
【详细过程】
闲来无事 逛至编程区 发现了好多教程 其中专题系列更是十分值得学习 看了玩命大侠的 第一篇文章
【成果6.1】软件保护壳技术专题 - 添加新节
http://bbs.pediy.com/showthread.php?p=467116
之后才明白自己为何平时用LDPE给文件加区段总是失败 呵呵 自以为收益颇丰
转念一想平时常用一工具 名曰zeroadd 跟文中提到之方甚为相似 遂肢解其文件 以求知
撰写此文 仅为笔记 高手嘲笑之余 望指点一二 愚弟拜谢……
此工具可谓清晰之至 win32ASM写的 反汇编出来基本根源码一样 奈何自己只是一只小菜虫 研究了整整一个晚上~
首先是看下流程
摘自 玩命 大侠 壳 专题 文章
其中 第6条 略过 因为在本文这不是重点。。
了解了大概思路就要开始动手了
OD加载zercadd.exe
先看主体函数
代码:
00401000 z>/$ 6A 00 push 0 ; /pModule = NULL 00401002 |. E8 7F050000 call ; \GetModuleHandleA 00401007 |. 6A 00 push 0 ; /lParam = NULL 00401009 |. 68 1F104000 push 0040101F ; |DlgProc = zeroadd.0040101F 0040100E |. 6A 00 push 0 ; |hOwner = NULL 00401010 |. 6A 01 push 1 ; |pTemplate = 1 00401012 |. 50 push eax ; |hInst 00401013 |. E8 20050000 call ; \DialogBoxParamA 00401018 |. 6A 00 push 0 ; /ExitCode = 0 0040101A \. E8 5B050000 call ; \ExitProcess
DialogBoxParamA的参数hInst为上面GetModuleHandleA得到的返回值 pTemplate为对话框资源ID DlgProc为对话框主函数体
我们跟随到主函数看看
又是很清晰的代码
主函数体很长 只做有用的摘录
代码:
00401030 |> \837D 0C 10 cmp dword ptr [ebp+C], 10 00401034 |. 75 0F jnz short 00401045 00401036 |. 6A 00 push 0 ; /Result = 0 00401038 |. FF75 08 push dword ptr [ebp+8] ; |hWnd 0040103B |. E8 FE040000 call ; \EndDialog
判断消息是否为WM_CLOSE 是的话不跳 call EndDialog结束对话框
代码:
00401045 |> \817D 0C 11010000 cmp dword ptr [ebp+C], 111 0040104C |. 0F85 31040000 jnz 00401483 00401052 |. 8B45 10 mov eax, dword ptr [ebp+10] 00401055 |. 66:83F8 02 cmp ax, 2 00401059 |. 75 58 jnz short 004010B3 0040105B |. C1E8 10 shr eax, 10 0040105E |. 66:0BC0 or ax, ax 00401061 |. 75 50 jnz short 004010B3 00401063 |. C705 F3324000 4C00>mov dword ptr [4032F3], 4C 0040106D |. C705 FF324000 3F33>mov dword ptr [4032FF], 0040333F ; ASCII "Executable Files (*.exe, *.dll)" 00401077 |. C705 0F334000 7C33>mov dword ptr [40330F], 0040337C 00401081 |. C705 13334000 0002>mov dword ptr [403313], 200 0040108B |. C705 27334000 0418>mov dword ptr [403327], 281804 00401095 |. 68 F3324000 push 004032F3 ; /pOpenFileName = zeroadd.004032F3 0040109A |. E8 11050000 call ; \GetOpenFileNameA
判断消息是否为WM_COMMAND 是则不跳 判断是否ID=2按下 之后初始化ofn结构 调用GetOpenFileNameA函数用系统对话框获得文件名
onf结构
typedef struct tagOFN {
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCTSTR lpstrFilter;
LPTSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPTSTR lpstrFile;
DWORD nMaxFile;
LPTSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCTSTR lpstrInitialDir;
LPCTSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCTSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
#if (_WIN32_WINNT >= 0x0500)
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
} OPENFILENAME, *LPOPENFILENAME;
VC++的介绍 详见 http://dev.csdn.net/article/13/13461.shtm
代码:
004010A4 |. 68 7C334000 push 0040337C ; /Text = "" 004010A9 |. 6A 03 push 3 ; |ControlID = 3 004010AB |. FF75 08 push dword ptr [ebp+8] ; |hWnd 004010AE |. E8 A3040000 call ; \SetDlgItemTextA
得到文件名后将其显示到ID=3的EDIT控件里
代码:
004010B3 |> \66:83F8 06 cmp ax, 6 004010B7 |. 0F85 7A030000 jnz 00401437 004010BD |. C1E8 10 shr eax, 10 004010C0 |. 66:0BC0 or ax, ax 004010C3 |. 0F85 6E030000 jnz 00401437 004010C9 |. 68 00020000 push 200 ; /Count = 200 (512.) 004010CE |. 68 20304000 push 00403020 ; |Buffer = zeroadd.00403020 004010D3 |. 6A 03 push 3 ; |ControlID = 3 004010D5 |. FF75 08 push dword ptr [ebp+8] ; |hWnd 004010D8 |. E8 67040000 call ; \GetDlgItemTextA 004010DD |. 68 00020000 push 200 ; /Count = 200 (512.) 004010E2 |. 68 00304000 push 00403000 ; |Buffer = zeroadd.00403000 004010E7 |. 6A 04 push 4 ; |ControlID = 4 004010E9 |. FF75 08 push dword ptr [ebp+8] ; |hWnd 004010EC |. E8 53040000 call ; \GetDlgItemTextA 004010F1 |. 68 00020000 push 200 ; /Count = 200 (512.) 004010F6 |. 68 08304000 push 00403008 ; |Buffer = zeroadd.00403008 004010FB |. 6A 05 push 5 ; |ControlID = 5 004010FD |. FF75 08 push dword ptr [ebp+8] ; |hWnd 00401100 |. E8 3F040000 call ; \GetDlgItemTextA 00401105 |. 6A 0F push 0F ; /ButtonID = F (15.) 00401107 |. FF75 08 push dword ptr [ebp+8] ; |hWnd 0040110A |. E8 3B040000 call ; \IsDlgButtonChecked
如果按下的是ID=6的BUTTEN 则读取三个EDIT控件的文字和一个CheckBox的状态
它们分别是 完整文件名 补区段的段名 段的大小 和是否备份源文件
代码:
0040110F |. 83F8 01 cmp eax, 1 00401112 |. 75 38 jnz short 0040114C 00401114 |. 68 20304000 push 00403020 ; /String2 = "" 00401119 |. 68 85304000 push 00403085 ; |String1 = zeroadd.00403085 0040111E |. E8 81040000 call ; \lstrcpyA 00401123 |. 68 1B314000 push 0040311B ; /StringToAdd = ".bak" 00401128 |. 68 85304000 push 00403085 ; |ConcatString = "" 0040112D |. E8 6C040000 call ; \lstrcatA 00401132 |. 6A 00 push 0 ; /FailIfExists = FALSE 00401134 |. 68 85304000 push 00403085 ; |NewFileName = "" 00401139 |. 68 20304000 push 00403020 ; |ExistingFileName = "" 0040113E |. E8 1F040000 call ; \CopyFileA 00401143 |. 83F8 00 cmp eax, 0 00401146 |. 0F84 51020000 je 0040139D 0040114C |> 6A 00 push 0 ; /FailIfExists = FALSE 0040114E |. 68 29314000 push 00403129 ; |NewFileName = "swapit.sca" 00401153 |. 68 20304000 push 00403020 ; |ExistingFileName = "" 00401158 |. E8 05040000 call ; \CopyFileA
如果call IsDlgButtonChecked的返回结构是1就是说明选中了备份文件 那么复制完整文件名 再文件名后面加上".bak"
之后拷贝文件 即完成了原文件的备份工作 呵呵 很简单哦~
再之后过程就和玩命大侠在文中叙述的几乎一样了 由于玩命大侠写得太清楚透彻了 我不再赘述 以免班门弄斧…
不过有一个函数引起了我的注意
代码:
00401190 |. 68 08304000 push 00403008 ; /Arg1 = 00403008 00401195 |. E8 13030000 call Hex> ; \zeroadd.004014AD
标签是我后来加的 原来是call 004014AD 这是这个程序为数不多的自己写的函数
跟过去看个究竟 看看他到底是干什么的
代码:
004014AD <>/$ 55 push ebp 004014AE |. 8BEC mov ebp, esp 004014B0 |. 83C4 FC add esp, -4 004014B3 |. 53 push ebx 004014B4 |. 51 push ecx 004014B5 |. 57 push edi 004014B6 |. 52 push edx 004014B7 |. 56 push esi 004014B8 |. C745 FC 00000000 mov dword ptr [ebp-4], 0 004014BF |. 33C9 xor ecx, ecx 004014C1 |. 8B7D 08 mov edi, dword ptr [ebp+8] 004014C4 |. FF75 08 push dword ptr [ebp+8] ; /String 004014C7 |. E8 DE000000 call ; \lstrlenA 004014CC |. BB 10000000 mov ebx, 10 004014D1 |. 8BF0 mov esi, eax 004014D3 |. EB 35 jmp short 0040150A 004014D5 |> 8A07 /mov al, byte ptr [edi] 004014D7 |. 3C 30 |cmp al, 30 ; Switch (cases 30..39) 004014D9 |. 72 08 |jb short 004014E3 ; 小于30跳 004014DB |. 3C 39 |cmp al, 39 004014DD |. 77 04 |ja short 004014E3 ; 大于39跳 004014DF |. 2C 30 |sub al, 30 ; 不跳就-30即为0~9 004014E1 |. EB 12 |jmp short 004014F5 004014E3 |> 3C 61 |cmp al, 61 ; Default case of switch 004014D7 004014E5 |. 72 0A |jb short 004014F1 004014E7 |. 3C 66 |cmp al, 66 004014E9 |. 77 06 |ja short 004014F1 004014EB |. 2C 61 |sub al, 61 004014ED |. 04 0A |add al, 0A 004014EF |. EB 04 |jmp short 004014F5 004014F1 |> 2C 41 |sub al, 41 004014F3 |. 04 0A |add al, 0A 004014F5 |> 0FB6C0 |movzx eax, al ; Cases 30 ('0'),31 ('1'),32 ('2'),33 ('3'),34 ('4'),35 ('5'),36 ('6'),37 ('7'),38 ('8'),39 ('9') of switch 004014D7 004014F8 |. 8BCE |mov ecx, esi 004014FA |. 49 |dec ecx 004014FB |. EB 03 |jmp short 00401500 004014FD |> F7E3 |/mul ebx 004014FF |. 49 ||dec ecx 00401500 |> 83F9 00 | cmp ecx, 0 00401503 |.^ 77 F8 |\ja short 004014FD 00401505 |. 0145 FC |add dword ptr [ebp-4], eax 00401508 |. 47 |inc edi 00401509 |. 4E |dec esi 0040150A |> 0BF6 or esi, esi 0040150C |.^ 75 C7 \jnz short 004014D5 0040150E |. 8B45 FC mov eax, dword ptr [ebp-4] 00401511 |. 5E pop esi 00401512 |. 5A pop edx 00401513 |. 5F pop edi 00401514 |. 59 pop ecx 00401515 |. 5B pop ebx 00401516 |. C9 leave 00401517 \. C2 0400 retn 4
一个完整的小函数 设计的相当精巧 类似于
代码:
long Fanc(LPSTR) { long dwM; .... ... .. . }
传入的参数是ID=5的EDIT里面的字符串 这个EDIT里面是我们输入的区段大小 猜想都可以知道 这个函数是把字符串转化为
HEX整型变量的 对于这个函数我十分感兴趣 但起初是觉得这一定是现成的函数 不用太在意 一定可以在网上找到 不过我错
了 的确是翻了很久 很久 在网上也没有找到一个比较完整好用的函数 于是分析了一下
先调用lstrlenA得到字符串的长度 之后就进入循环 读入一个字节 比较该字节的ascii值 30h~39h就直接减去30h 即为0~9
如果是61h~66h就减去61h之后在加上0Ah 就是0Ah~0Fh 之后用这个值去乘以10h 分别乘以当前esi-1次 即实现了进位
之后出乘法小循环 把中间结果保存在局部变量里 字符串指针+1 esi变量-1 再去循环 知道最后esi为0 退出大循环
最后的结果保存在 EAX寄存器里……
好了 大概经过我们都明白了 这个程序就像是自己的了 看哪里都知道原理 呵呵 但这还不是我们的最终目的 嘻嘻
知道原理就要实现 逆向高级语言都不怕难 何况这种会编写的清晰的都告诉你API的程序呢
所以ASM写了自己的一个小工具 对他的代码某些部分进行了优化
代码里引用了 玩命 大侠 在《【成果6.1】软件保护壳技术专题 - 添加新节》 一文中的代码 稍作修改 主要是不敢班门弄斧
代码中引用了 罗云斌 @公用子程序部分:窗口部分 将窗口移动到屏幕中间函数
代码:
.386 .model flat, stdcall option casemap:none ;; ---------------------------------------- ;; header file and lib file ;; ---------------------------------------- include kernel32.inc include user32.inc include comdlg32.inc includelib kernel32.lib includelib user32.lib includelib comdlg32.lib include windows.inc PEAlign proto dwTarNum : DWORD, dwAlignTo : DWORD AddSection proto pMem : LPVOID, pSectionName : LPVOID, dwSectionSize : DWORD ;DLGproc proto dlghwnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM ;_CenterWindow proto :DWORD ;将窗口移动到屏幕中间 by 罗云彬@公用子程序部分:窗口部分 APPEND_SIZE equ 2000h .data ofn OPENFILENAME <> lpstrFilter db "eXe Files(*.eXe)",0 lpstrFile db 255 dup(0) lpstrBAKFile db 255 dup(0) lpBAK db ".bak",0 lpsectionName db 8 dup(0) lpsectionSize db 8 dup(0) ;//////////////////////////////////////////////////////////////// ;以下变量定义摘自"玩命"大侠 【成果6.1】软件保护壳技术专题 - 添加新节 ;//////////////////////////////////////////////////////////////// g_szErr db "错误",0 g_szDone db "文件加密成功!",0 g_szDoneCap db "^_^",0 g_szOpenFileFailed db "打不开文件",0 g_szGetFileSizeFailed db "获取文件大小失败",0 g_szCreateMapFailed db "创建文件映射失败",0 g_szMapFileFailed db "映射文件到内存失败",0 g_szInvalidPE db "无效的PE文件",0 g_bError db 0 g_dwNewSectionSize dd 0 .code ;//////////////////////////////////////////////////////////////// ;以下函数修改自"玩命"大侠 【成果6.1】软件保护壳技术专题 - 添加新节 ;http://bbs.pediy.com/showthread.php?p=467116 ;一文,稍作改动 ;//////////////////////////////////////////////////////////////// CryptFile proc szFname : LPSTR,szSectionName:LPSTR,dwSectionSize:DWORD LOCAL hFile : HANDLE LOCAL hMap : HANDLE LOCAL pMem : LPVOID LOCAL dwOrigFileSize : DWORD LOCAL dwNTHeaderAddr : DWORD ;; init data xor eax, eax mov g_bError, al mov eax, dwSectionSize mov g_dwNewSectionSize, eax ;; open file invoke CreateFile, szFname,\ GENERIC_WRITE + GENERIC_READ,\ FILE_SHARE_WRITE + FILE_SHARE_READ,\ NULL,\ OPEN_EXISTING,\ FILE_ATTRIBUTE_NORMAL,\ 0 .IF eax == INVALID_HANDLE_VALUE jmp OpenFileFailed .ENDIF mov hFile, eax invoke GetFileSize, hFile, NULL .IF eax == 0 invoke CloseHandle, hFile jmp GetFileSizeFailed .ENDIF mov dwOrigFileSize, eax add eax, APPEND_SIZE xchg eax, ecx ;; create memory map xor ebx, ebx invoke CreateFileMapping, hFile, ebx, PAGE_READWRITE, ebx, ecx, ebx .IF eax == 0 invoke CloseHandle, hFile jmp CreateMapFailed .ENDIF mov hMap, eax ;; map file to memory invoke MapViewOfFile, hMap, FILE_MAP_WRITE+FILE_MAP_READ+FILE_MAP_COPY, ebx, ebx, ebx .IF eax == 0 invoke CloseHandle, hMap invoke CloseHandle, hFile jmp MapFileFailed .ENDIF mov pMem, eax ;; check it's PE file or not ? xchg eax, esi assume esi : ptr IMAGE_DOS_HEADER .IF [esi].e_magic != 'ZM' invoke UnmapViewOfFile, pMem invoke CloseHandle, hMap invoke CloseHandle, hFile jmp InvalidPE .ENDIF add esi, [esi].e_lfanew assume esi : ptr IMAGE_NT_HEADERS .IF word ptr [esi].Signature != 'EP' invoke UnmapViewOfFile, pMem invoke CloseHandle, hMap invoke CloseHandle, hFile jmp InvalidPE .ENDIF mov dwNTHeaderAddr, esi invoke AddSection, pMem,szSectionName, g_dwNewSectionSize push eax mov esi, dwNTHeaderAddr assume esi : ptr IMAGE_NT_HEADERS LogicShellExit: ;; close handle & write it invoke UnmapViewOfFile, pMem invoke CloseHandle, hMap invoke CloseHandle, hFile .IF g_bError == 0 ;; show success message invoke MessageBox, NULL, offset g_szDone, offset g_szDoneCap, MB_ICONINFORMATION .ENDIF ret ;; ----- Show error message ----- OpenFileFailed: lea eax, g_szOpenFileFailed jmp ShowErr GetFileSizeFailed: lea eax, g_szGetFileSizeFailed jmp ShowErr CreateMapFailed: lea eax, g_szCreateMapFailed jmp ShowErr MapFileFailed: lea eax, g_szMapFileFailed jmp ShowErr InvalidPE: lea eax, g_szInvalidPE jmp ShowErr ShowErr: invoke MessageBox, NULL, eax, offset g_szErr, MB_ICONERROR mov al, 1 mov g_bError, al jmp LogicShellExit CryptFile endp AddSection proc uses ebx ecx edx esi edi, pMem : LPVOID, pSectionName : LPVOID, dwSectionSize : DWORD ;; add a new section ;; ret: eax = new section table file offset LOCAL dwNTHeader : LPVOID LOCAL dwLastSecTbl : LPVOID LOCAL dwFileAlig : DWORD LOCAL dwSecAlig : DWORD ;; move to section table mov esi, pMem ;; assume esi : ptr IMAGE_DOS_HEADER ;; add esi, dword ptr [esi].e_lfanew add esi, dword ptr [esi+3ch] mov dwNTHeader, esi assume esi : ptr IMAGE_NT_HEADERS ;; update the number of section mov cx, word ptr [esi].FileHeader.NumberOfSections movzx ecx, cx inc word ptr [esi].FileHeader.NumberOfSections push dword ptr [esi].OptionalHeader.FileAlignment pop dwFileAlig push dword ptr [esi].OptionalHeader.SectionAlignment pop dwSecAlig ;; move esi point to section table add esi, sizeof IMAGE_NT_HEADERS ;; store the last section table mov eax, sizeof IMAGE_SECTION_HEADER mov ebx, ecx imul ebx add esi, eax ; esi = the end of orig last section fva push esi sub esi, sizeof IMAGE_SECTION_HEADER ; esi = the orig last section fva mov dwLastSecTbl, esi pop esi ;; set new section table assume esi : ptr IMAGE_SECTION_HEADER ;; set section name push esi lea edi, [esi].Name1 mov esi, pSectionName CopySectionNameLoop: lodsb test al, al jz EndCopySectionNameLoop stosb jmp CopySectionNameLoop EndCopySectionNameLoop: pop esi push 0E00000E0h pop dword ptr [esi].Characteristics push dwSectionSize pop dword ptr [esi].Misc.VirtualSize invoke PEAlign, dwSectionSize, dwFileAlig mov dword ptr [esi].SizeOfRawData, eax mov eax, dwLastSecTbl ; eax = orig last section table fva assume eax : ptr IMAGE_SECTION_HEADER mov ecx, dword ptr [eax].VirtualAddress add ecx, dword ptr [eax].Misc.VirtualSize ; ecx = new section rva mov ebx, dword ptr [eax].PointerToRawData add ebx, dword ptr [eax].SizeOfRawData ; ebx = new section fva invoke PEAlign, ecx, dwSecAlig mov dword ptr [esi].VirtualAddress, eax ;; set section pointertorawdata invoke PEAlign, ebx, dwFileAlig mov dword ptr [esi].PointerToRawData, eax mov eax, dword ptr [esi].VirtualAddress add eax, dword ptr [esi].Misc.VirtualSize invoke PEAlign, eax, dwSecAlig mov edx, dwNTHeader assume edx : ptr IMAGE_NT_HEADERS mov dword ptr [edx].OptionalHeader.SizeOfImage, eax push dword ptr [esi].PointerToRawData pop edi add edi, pMem ;; clear the new sec mov ecx, dwSectionSize xor eax, eax cld rep stosb mov eax, esi assume esi : nothing assume eax : nothing assume edx : nothing ret AddSection endp PEAlign proc uses ecx edx, dwTarNum : DWORD, dwAlignTo : DWORD ;; returns aligned value ;; Algorithms: ;; $1 = dwTarNum / dwAlignTo ;; if remain != 0 ;; $r = $1 + 1 * dwAlignTo ;; return $r mov ecx, dwAlignTo mov eax, dwTarNum xor edx, edx div ecx cmp edx, 0 jz AlreadyAligned inc eax AlreadyAligned: mul ecx ret PEAlign endp ;//////////////////////////////////////////////////////////////////////// ;引用代码结束 ;//////////////////////////////////////////////////////////////////////// _CenterWindow proc hWnd:DWORD local @stRectDeskTop:RECT,@stRectWin:RECT local @dwWidth:DWORD,@dwHeight:DWORD invoke GetWindowRect,hWnd,addr @stRectWin invoke GetDesktopWindow mov ebx,eax invoke GetWindowRect,ebx,addr @stRectDeskTop mov eax,@stRectWin.bottom sub eax,@stRectWin.top mov @dwHeight,eax mov eax,@stRectWin.right sub eax,@stRectWin.left mov @dwWidth,eax mov ebx,@stRectDeskTop.bottom sub ebx,@dwHeight shr ebx,1 mov ecx,@stRectDeskTop.right sub ecx,@dwWidth shr ecx,1 invoke MoveWindow,hWnd,ecx,ebx,@dwWidth,@dwHeight,FALSE ret _CenterWindow endp LpstrToHex proc uses esi edi ecx edx ebx, lpstr:LPSTR LOCAL dwM:DWORD mov ebx,10h mov edi,lpstr mov dwM,0 invoke lstrlen,lpstr mov esi,eax looop3: .if esi>0 mov al,byte ptr [edi] .if al>=30h .if al<=39h sub al,30h jmp looop .elseif al>=61h .if al<=66h sub al,61h add al,0ah jmp looop .elseif al>=41h .if al<=46h sub al,41h add al,0ah jmp looop .endif .endif .endif looop: movzx eax,al mov ecx,esi dec ecx looop2: .if ecx>0 mul ebx dec ecx jmp looop2 .endif add dwM,eax inc edi dec esi jmp looop3 .endif .endif mov eax,dwM ret LpstrToHex endp DLGproc proc dlghwnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM mov eax,uMsg .if eax == WM_CLOSE invoke EndDialog,dlghwnd,NULL ;******************************************************************** .elseif eax == WM_INITDIALOG invoke _CenterWindow,dlghwnd ;******************************************************************** .elseif eax == WM_COMMAND mov eax,wParam movzx eax,ax .if eax == 1001 mov ofn.lStructSize,sizeof ofn mov eax,offset lpstrFilter ;初始化ofn结构 mov ofn.lpstrFilter,eax mov eax,offset lpstrFile mov ofn.lpstrFile,eax mov ofn.nMaxFile,sizeof lpstrFile mov ofn.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST invoke GetOpenFileName,addr ofn .if eax==1 invoke SetDlgItemText,dlghwnd,1003,ofn.lpstrFile .endif .elseif eax==1008 invoke IsDlgButtonChecked,dlghwnd,1002 .if eax==1 invoke lstrcpy,offset lpstrBAKFile,offset lpstrFile invoke lstrcat,offset lpstrBAKFile,offset lpBAK invoke CopyFile,offset lpstrFile,offset lpstrBAKFile,0 .endif invoke GetDlgItemText,dlghwnd,1003,offset lpstrFile,255 invoke GetDlgItemText,dlghwnd,1005,offset lpsectionName,8 invoke GetDlgItemText,dlghwnd,1007,offset lpsectionSize,8 invoke LpstrToHex,offset lpsectionSize invoke CryptFile,offset lpstrFile,offset lpsectionName,eax .endif ;******************************************************************** ; 注意:对话框的消息处理后,要返回 TRUE,对没有处理的消息 ; 要返回 FALSE ;******************************************************************** .else mov eax,FALSE ret .endif mov eax,TRUE ret DLGproc endp start: invoke GetModuleHandle,0 invoke DialogBoxParam,eax,1000,0,addr DLGproc,0 invoke ExitProcess,0 end start
附上资源脚本
代码:
#define IDD_DLG1 1000 #define IDC_BTN1 1001 #define IDC_CHK1 1002 #define IDC_STC1 1003 #define IDC_STC2 1004 #define IDC_EDT1 1005 #define IDC_STC3 1006 #define IDC_EDT2 1007 #define IDC_BTN2 1008 #define IDR_VERSION 1 IDD_DLG1 DIALOGEX 6,6,99,108 CAPTION "SCTaDD_BY_eASYSCt" FONT 8,"MS Sans Serif",0,0 STYLE 0x10CA0000 BEGIN CONTROL "打开文件",IDC_BTN1,"Button",0x50010000,4,1,92,15 CONTROL "备份源文件",IDC_CHK1,"Button",0x50010003,4,20,92,15 CONTROL "",IDC_STC1,"Static",0x50000000,2,40,94,13 CONTROL "新区段名",IDC_STC2,"Static",0x50000000,2,60,36,9 CONTROL "",IDC_EDT1,"Edit",0x50010000,46,57,50,15,0x00000200 CONTROL "新区段大小",IDC_STC3,"Static",0x50000000,2,77,42,9 CONTROL "",IDC_EDT2,"Edit",0x50010000,46,73,50,15,0x00000200 CONTROL "增加区段",IDC_BTN2,"Button",0x50010000,4,90,92,13 END IDR_VERSION VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 FILEOS 0x00000004 FILETYPE 0x00000000 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "FFFF0000" BEGIN VALUE "FileVersion", "1.0.0.0\0" VALUE "ProductVersion", "1.0.0.0\0" VALUE "CompanyName", "hIMcrACk\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0xFFFF, 0x0000 END END
玩命 大侠的代码在http://bbs.pediy.com/showthread.php?p=467116有详细注释的 像我一样的小菜虫可以去阅读~
其中 函数LpstrToHex为自己优化后的字符串转16进制整型变量的函数 算法上不算高明 结构上不算美观 不过能够达到效用
有需要的朋友可以拿去使用~~
期待大牛们逆出效率更高 结构更漂亮的函数 以供收藏……
天快亮了 就不多写了 最后把工具上传 喜欢就拿去用~
感谢你耐心的看到这里 为能忍受菜菜的笔记所感谢~
【经验总结】
PE文件结构基础 asm的练习 细心coding 耐心debuging是最大收获
tHAT is ALl
THX!!!!
2008年11月23日 6:16:55