给OD添加工具菜单
大家好,第一次写这种文章,写的不好,请见谅,有什么不明白的地方,请提出,谢谢!
OD是我们常用的一个软件调试,在这里我就不做多的介绍了,进入正题
参考文章:API手册,打造自己喜欢的 Ollydbg、看雪论坛精华7中的文章
修改流程->增加空间->添加函数->找插入菜单的位置->读取配置列表->插入菜单->处理工具菜单事件 第一步,增加空间,肯定需要有空间了,OD本身是不够的,我们用ZeroAdd,为OD添加一个区段,大小为2000(HEX),名字patch,把我们所要写的代码写到这个区段中
第二步,添加函数,我们这次用到是lstrlenA,这个函数取数据,打开LoaderPE->PE编辑->修改的OD->目录->单击“输入表”后面的"..."按钮,打开输入表对话,在OLE32.dll这行单击右键选择“添加导入表”,在打开的“添加导入函数”窗口中DLL处输入:Kernel32.dll,在API处,输入“lstrlenA”,点确定->关闭添加导入表对话框->保存->保存->关闭Loadpe,到时函数添加完成
第三步,找OD启动时的消息流,让他根本我们的配置加载工具菜单。方法:大家都知道,OD在启动后会加载插件,就让OD添加插件菜单后,添加我们的工具菜单吧。用另一个OD打开我们要修改的OD,插入菜单的API是InsertMenu,
在OD命令行输入bp InsertMenuA,F9运行,OD断下,Alt+F9返回,来到这里
00496B06 |. 51 PUSH ECX ; /pNewItem
00496B07 |. 8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C] ; |
00496B0B |. 50 PUSH EAX ; |NewItemID
00496B0C |. 68 10040000 PUSH 410 ; |Flags = MF_BYPOSITION|MF_ENABLED|MF_STRING|MF_POPUP
00496B11 |. 6A 03 PUSH 3 ; |ItemID = 3
00496B13 |. 8B15 7C3B4D00 MOV EDX,DWORD PTR DS:[4D3B7C] ; |
00496B19 |. 52 PUSH EDX ; |/hWnd => 0014056A (class='Aytcgjb')
00496B1A |. E8 49890100 CALL <JMP.&USER32.GetMenu> ; |\GetMenu
00496B1F |. 50 PUSH EAX ; |hMenu
00496B20 |. E8 9D890100 CALL <JMP.&USER32.InsertMenuA> ; \InsertMenuA
00496B25 |. 8B0D 7C3B4D00 MOV ECX,DWORD PTR DS:[4D3B7C]
00496B2B |. 51 PUSH ECX ; /hWnd => 0014056A (class='Aytcgjb')
00496B2C |. E8 A1880100 CALL <JMP.&USER32.DrawMenuBar> ; \DrawMenuBar
断续返回
00438EE6 . 833D B8544D00>CMP DWORD PTR DS:[4D54B8],0
00438EED . 0F84 27010000 JE ollydbgb.0043901A
00438EF3 . C705 C8544D00>MOV DWORD PTR DS:[4D54C8],1
00438EFD . F605 CC544D00>TEST BYTE PTR DS:[4D54CC],2
00438F04 . 74 05 JE SHORT ollydbgb.00438F0B
00438F06 . E8 E5220200 CALL ollydbgb._Createlistwindow
00438F0B > F605 CC544D00>TEST BYTE PTR DS:[4D54CC],4
此时,OD已经添加了插件菜单,该我们动手了,
第四步,插入工具菜单
566000-5667FFE是我们添加的空间
00438EE6 CMP DWORD PTR DS:[4D54B8],0 改成 JMP 005661FE 跳到我们的空间去
字符串"Tools",ollydbg.ini中的工具列表区节的区节名,OD添加如下
005661E6 54 PUSH ESP
005661E7 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O 命令
005661E8 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O 命令
005661E9 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
005661EA 73 00 JNB SHORT 复件_oll.005661EC
字符串"工具(&T)",为OD添加的菜单名称
005661D5 B9 A4BEDF28 MOV ECX,28DFBEA4
005661DA 26:54 PUSH ESP ; 多余的前缀
005661DC 2900 SUB DWORD PTR DS:[EAX],EAX DIY一定要注意的问题,一、堆栈平台问题,二、跨平台问题,本人首次修改,都遇到了
流程->读取工具列表名称->添加到一个菜单中-》插入菜单
用到函数:
创建一个菜单,如果成功返回创建菜单的句柄,没有参数
HMENU CreateMenu(VOID);
取INI的配置文件,如果lpKeyName为NULL,则读取这个区节中所有工具名称
DWORD GetPrivateProfileString(
LPCTSTR lpAppName, // section name
LPCTSTR lpKeyName, // key name
LPCTSTR lpDefault, // default string
LPTSTR lpReturnedString, // destination buffer
DWORD nSize, // size of destination buffer
LPCTSTR lpFileName // initialization file name
);
把读取到的工具名称,追到了一个菜单中,我们要用他,把读取的工具名称添加到菜单句柄
BOOL AppendMenu(
HMENU hMenu, // handle to menu
UINT uFlags, // menu-item options
UINT_PTR uIDNewItem, // identifier, menu, or submenu
LPCTSTR lpNewItem // menu-item content
);
把创建的菜单添加到OD的菜单中
BOOL InsertMenu(
HMENU hMenu, // handle to menu
UINT uPosition, // item that new item precedes
UINT uFlags, // options
UINT_PTR uIDNewItem, // identifier, menu, or submenu
LPCTSTR lpNewItem // menu item content
);
重画菜单栏
BOOL DrawMenuBar(
HWND hWnd // handle to window
);
堆栈平衡问题:做完以后遇到堆栈平台问题,popad出栈时,堆栈中参数少了一个,所以使用使用两次PUSHAD,大家以后再DIY时,注意一下。
我们开始了
005661FE 9C PUSHFD 寄存器之栈
005661FF 60 PUSHAD
00566200 60 PUSHAD
00566201 68 A4534D00 PUSH 复件_oll.004D53A4 ; INI的文件路径
00566206 68 00020000 PUSH 200 ; 200个字节的位置
0056620B 68 00775600 PUSH 复件_oll.00567700 ; 存放取出字符串的地址
00566210 68 F4615600 PUSH 复件_oll.005661F4
00566215 6A 00 PUSH 0
00566217 68 E6615600 PUSH 复件_oll.005661E6 ; ASCII "Tools"
0056621C E8 698EF4FF CALL <JMP.&KERNEL32.GetPrivateProfileStr>
读取ini中的工具名列表
00566221 BF 00775600 MOV EDI,复件_oll.00567700
00566226 803F 00 CMP BYTE PTR DS:[EDI],0
00566229 ^ 0F84 49FFFFFF JE 复件_oll.00566178
这里列表是否为空,如果为空,则直接跳回返回处
0056622F E8 5C91F4FF CALL <JMP.&USER32.CreateMenu>
00566234 8BD8 MOV EBX,EAX
00566236 75 05 JNZ SHORT 复件_oll.0056623D
00566238 ^ E9 44FFFFFF JMP 复件_oll.00566181
创建一个菜单句柄,如果失败,跳到返回处
0056623D BE F10A0000 MOV ESI,0AF1 0AF1是第一个菜单的ID=2801
00566242 57 PUSH EDI EDI的地址中存放要添加的工具名称
00566243 56 PUSH ESI 菜单的ID
00566244 6A 00 PUSH 0 指定添加方式
00566246 53 PUSH EBX 追到菜单的句柄
00566247 E8 0291F4FF CALL <JMP.&USER32.AppendMenuA>
添加一个菜单
0056624C 57 PUSH EDI
0056624D E9 38010000 JMP 复件_oll.0056638A lstrlenA,跨平台问题移动下面
00566252 03F8 ADD EDI,EAX 地址+长度+1=下一个工具名的位置
00566254 47 INC EDI
00566255 46 INC ESI 菜单ID也要加1
00566256 803F 00 CMP BYTE PTR DS:[EDI],0
00566259 ^ 75 E7 JNZ SHORT 复件_oll.00566242
如果读完后,继续
0056625B 68 D5615600 PUSH 复件_oll.005661D5
00566260 53 PUSH EBX
00566261 68 10040000 PUSH 410
00566266 6A 05 PUSH 5
00566268 8B15 7C3B4D00 MOV EDX,DWORD PTR DS:[4D3B7C]
0056626E 52 PUSH EDX
0056626F E8 F491F4FF CALL <JMP.&USER32.GetMenu>
00566274 50 PUSH EAX
00566275 E8 4892F4FF CALL <JMP.&USER32.InsertMenuA>
插入菜单,参加OD插入插件菜单的方法
0056627A 8B0D 7C3B4D00 MOV ECX,DWORD PTR DS:[4D3B7C]
00566280 E8 4D91F4FF CALL <JMP.&USER32.DrawMenuBar>
重画菜单栏
00566285 ^ E9 EFFEFFFF JMP 复件_oll.00566179
跳到返回处 返回处代码
00566178 58 POP EAX
00566179 58 POP EAX
0056617A 58 POP EAX
0056617B 58 POP EAX
0056617C 58 POP EAX
0056617D 58 POP EAX
0056617E 58 POP EAX
0056617F 58 POP EAX
00566180 61 POPAD
00566181 9D POPFD
00566182 833D B8544D00 0>CMP DWORD PTR DS:[4D54B8],0
00566189 - E9 5F2DEDFF JMP 复件_oll.00438EED 字符串"kernel32.dll"
00566372 6B65 72 6E IMUL ESP,DWORD PTR SS:[EBP+72],6E
00566376 65:6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
00566378 3332 XOR ESI,DWORD PTR DS:[EDX]
0056637A 2E: PREFIX CS: ; 多余的前缀
0056637B 64:6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
0056637D 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
字符串"lstrlenA"
00566380 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
00566381 73 74 JNB SHORT 复件_oll.005663F7
00566383 72 6C JB SHORT 复件_oll.005663F1
00566385 65:6E OUTS DX,BYTE PTR ES:[EDI] ; I/O 命令
00566387 41 INC ECX
由于OD这个函数,故采用这种方法来使用该函数,参考看雪论坛7中的记事本置顶中看雪的问题回复
未解决跨平台,导致写的比较乱,请见谅
0056638A 68 72635600 PUSH 复件_oll.00566372 ; ASCII "kernel32.dll"
0056638F E8 DE8CF4FF CALL <JMP.&KERNEL32.GetModuleHandleA>
00566394 68 80635600 PUSH 复件_oll.00566380 ; ASCII "lstrlenA"
00566399 50 PUSH EAX
0056639A E8 F18CF4FF CALL <JMP.&KERNEL32.GetProcAddress>
0056639F FFD0 CALL EAX
005663A1 ^ E9 ACFEFFFF JMP 复件_oll.00566252
这样就会OD插入了一个工具菜单,但菜单无法响应事件,我们继续
第五,让添加的工具菜单响应事件,为了能识别相对路径,我们采用CreateProcessA函数和完成
流程->取选择的工具名称->读取路径->执行读取的路径
所有函数原型
int GetMenuString(
HMENU hMenu, // handle to the menu
UINT uIDItem, // menu item identifier
LPTSTR lpString, // buffer for the string
int nMaxCount, // maximum length of string
UINT uFlag // options
);
VOID GetStartupInfo(
LPSTARTUPINFO lpStartupInfo // address of STARTUPINFO structure
);
BOOL CreateProcess(
LPCTSTR lpApplicationName, // pointer to name of executable module
LPTSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCTSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION
);
找消息循环的位置
我找的位置
00433A1F |> \81EA C7090000 SUB EDX,9C7
00433A25 |. 0F84 37070000 JE ollydbgb.00434162
改成
00433A1F >-\E9 7C281300 JMP 复件_oll.005662A0
00433A24 90 NOP 005662A0 81FA F00A0000 CMP EDX,0AF0 如果这个根本不我们工具菜单ID 返回
005662A6 ^ 7C E4 JL SHORT 复件_oll.0056628C
005662A8 81FA 0E0B0000 CMP EDX,0B0E 0B0E是2830,目录只支持30个,想要多的话,大家改大一下就行了
大于这个不是我们的菜单ID,返回
005662AE ^ 7F DC JG SHORT 复件_oll.0056628C 005662B0 6A 00 PUSH 0
005662B2 6A 30 PUSH 30
005662B4 68 00705600 PUSH 复件_oll.00567000 存放我们取到的工具名
005662B9 52 PUSH EDX
005662BA 8B15 7C3B4D00 MOV EDX,DWORD PTR DS:[4D3B7C]
005662C0 52 PUSH EDX
005662C1 E8 A291F4FF CALL <JMP.&USER32.GetMenu>
005662C6 50 PUSH EAX
005662C7 E8 AE91F4FF CALL <JMP.&USER32.GetMenuStringA>
把取到的菜单工具名放到567000这个地址处
005662CC 68 A4534D00 PUSH 复件_oll.004D53A4
005662D1 6A 70 PUSH 70
005662D3 68 40705600 PUSH 复件_oll.00567040
005662D8 68 F4615600 PUSH 复件_oll.005661F4
005662DD 68 00705600 PUSH 复件_oll.00567000
005662E2 68 E6615600 PUSH 复件_oll.005661E6 ; ASCII "Tools"
005662E7 E8 9E8DF4FF CALL <JMP.&KERNEL32.GetPrivateProfileStr>
根据取的工具名取出相应的路径 005662EC 68 20715600 PUSH 复件_oll.00567120
005662F1 E8 A68DF4FF CALL <JMP.&KERNEL32.GetStartupInfoA>
005662F6 68 66715600 PUSH 复件_oll.00567166
005662FB 68 20715600 PUSH 复件_oll.00567120
00566300 6A 00 PUSH 0
00566302 6A 00 PUSH 0
00566304 6A 20 PUSH 20
00566306 6A 00 PUSH 0
00566308 6A 00 PUSH 0
0056630A 6A 00 PUSH 0
0056630C 68 40705600 PUSH 复件_oll.00567040
00566311 6A 00 PUSH 0
00566313 E8 B88CF4FF CALL <JMP.&KERNEL32.CreateProcessA>
把路径放到CreateProcess中执行,让他打开就行了
00566318 - E9 F5DEECFF JMP 复件_oll.00434212 跳回默认消息处 到此,工具菜单就添加到OD中了,为了能方便的配置OD,写了一个简单配置程序,放到Tools下了.
用ResHacker 给选项菜单加一个“工具菜单的配置”ID为2305
添加代码的方法和上面一样,找消息循环,执行程序,源码下面 0056600E 81FA 01090000 CMP EDX,901
00566014 74 1F JE SHORT 复件_oll.00566035
00566016 81EA 61090000 SUB EDX,961
0056601C - E9 BDD9ECFF JMP 复件_oll.004339DE
00566021 90 NOP
字符串"tools\tools.exe"
00566022 0000 ADD BYTE PTR DS:[EAX],AL
00566024 74 6F JE SHORT 复件_oll.00566095
00566026 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O 命令
00566027 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
00566028 73 5C JNB SHORT 复件_oll.00566086
0056602A 74 6F JE SHORT 复件_oll.0056609B
0056602C 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O 命令
0056602D 6C INS BYTE PTR ES:[EDI],DX ; I/O 命令
0056602E 73 2E JNB SHORT 复件_oll.0056605E
00566030 65:78 65 JS SHORT 复件_oll.00566098 ; 多余的前缀
00566033 0000 ADD BYTE PTR DS:[EAX],AL
执行代码
00566035 68 B1605600 PUSH 复件_oll.005660B1
0056603A E8 5D90F4FF CALL <JMP.&KERNEL32.GetStartupInfoA>
0056603F 68 F5605600 PUSH 复件_oll.005660F5
00566044 68 B1605600 PUSH 复件_oll.005660B1
00566049 6A 00 PUSH 0
0056604B 6A 00 PUSH 0
0056604D 6A 20 PUSH 20
0056604F 6A 00 PUSH 0
00566051 6A 00 PUSH 0
00566053 6A 00 PUSH 0
00566055 68 24605600 PUSH 复件_oll.00566024 ; ASCII "tools\tools.exe"
0056605A 6A 00 PUSH 0
0056605C E8 6F8FF4FF CALL <JMP.&KERNEL32.CreateProcessA>
00566061 - E9 ACE1ECFF JMP 复件_oll.00434212 好了,到些结束,修修补补,代码比较乱,慢慢看吧,第一次写这么多,可以有些东西没有说明白,回复中提问。
下载地址: http://www.fs2you.com/files/eea01547-be8f-11dc-9541-0014221b798a/
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)