- UID
- 2
- 精华
- 积分
- 7736
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
这是从ollydbg官网http://www.ollydbg.de/翻译过来的:
ollydbg是一个windows下的32位汇编级分析调试器,在没有源码的情况下对于二进制代码的分析能力显得尤为重要。ollydbg是一个共享软件,但是可以自由的下载使用,它的特点如下:
直观的用户界面没有隐藏命令
代码分析 - 跟踪寄存器,识别函数过程,跳转,api调用,开关语句,表,常量和字符串
直接加载并调试dll
目标文件的扫描 - 从目标文件和库中定位函数
允许用户自定义标签注释和功能描述
可以分析Borland格式的调试信息
保存会话中的信息,并更新写回到可执行文件
开放式体系 - 支持第三方插件
无需安装 - 不会再注册表和系统中产生垃圾
调试多线程程序
附加到进程
可配置的反汇编器,支持masm和ideal格式
支持MMX,3DNow!,SSE数据类型和指令,支持Athlon扩展指令
全面支持UNICODE
动态识别ASCII和UNICODE字符串 - 支持Delphi格式的
识别复杂代码的结构,例如call,jump到某个过程
识别超过1900个api和400个c函数调用
由外部帮助文件可获取api函数的上下文帮助
设置条件断点,条件记录断点,内存断点和硬件断点
跟踪程序执行,记录已知函数参数
显示修正
动态跟踪栈帧
支持搜索模糊命令和掩码二进制序列
搜索全部分配的内存
寻找常量和地段标记
查看和修改内存,设置断点,暂停程序执行
将命令汇编成最短二进制形式
从软盘运行
Plugin Development Kit 1.10
ollydbg插件开发
编译
要编译你自己的插件,需要c或c++编译器(有运行库和链接器),插件接口(plugin.h文件)最低兼容以下编译器:
Borland C++ 5.5
Borland C++ Builder 5
Microsoft Visual C++ 5.0
插件开发工具包包括2个全功能插件的源代码:
书签插件,让你为被调试程序设置多达10个书签;命令行插件,实现了命令行接口 。插件都是未文档化的你可以作为模板开发自己的插件,他们都是免费的。
需要如下设置编译器才能使插件和ollydbg正常通信,除了上述那些编译器,plugin.h还按如下规则检查:
通过名称导出函数而非序号
如果你使用c++编译器需要在所有回调函数中禁用名称粉碎(声明为extern "C")
强制使用C格式给api或者回调函数传递参数(声明为cdecl)
对于plugin.h中声明的结构体,强制按1字节对齐
设置默认字符类型为UNSIGNED
记得所有从ollydbg获取的指针都可能是空,忽略这一点是常见错误
使用静态运行库直接链接到你的插件,否则不同版本运行时dll会使ollydbg不稳定。不要把你的插件不必要滴分为若干个dll,如果你需要数据文件且不想让用户修改,试着将这些数据作为资源直接写入你的插件。为了让ollydbg连接你的插件,需要链接ollydbg.lib,一些编译器,如Borland,包含了implib工具可以扫描可执行文件(ollydbg.exe),并产生一个特殊的库记录所有导出函数,另一些编译器例如(vc)可以从def文件(ollydbg.def)生成导入库。类似的产品请阅读他们的文档。
请不要浪费资源,不要输出未使用的回调函数,这样可以是的你的程序更快,ollydbg当前的版本支持多达32个插件。
用vc5从命令行编译插件例子:
1.将bookmar.c,cmdexec.c,command.c,plugin.h,vc50\bookmar.mak,vc50\cmdline.mak,vc50\ollydbg.lib复制到相同目录
2.编辑mak文件
INCLUDE=c:\vc\include
LIBPATH=c:\vc\lib
这样他们就可以指向你的头文件和库文件目录了
3.进入c:\vc\bin,执行
c:\vc\bin\nmake -f bookmark.mak
c:\vc\bin\nmake -f cmdline.mak
4.使用vs编译插件
编译bookmark.dll
1.将bookmark.c, plugin.h, vc50\bookmark.dsp, vc50\bookmark.dsw vc50\ollydbg.lib 复制到同一目录
2.使用vs打开bookmark工程,编译
教程1:运行时跟踪
运行时跟踪技术是在ollydbg1.04首次引入的,这种调试技术基本都很简单。代码是一步步执行的,调试器使用环形缓冲区处理每个命令,寄存器和标志位。当发生异常时可以多次回退到上个命令,分析出错条件。
ollydbg1.06显著提高了运行跟踪的可能性,运行跟踪会系那是修改的寄存器,保留重要的信息和已知函数操作。使用此技术我们可以设置条件暂停运行跟踪,分析跟踪代码,在磁盘里记录跟踪日志克服内存限制,或者比较2个运行实例,调试自修改程序,寻找执行了最后一次的指令,等等
无论如何这个过程都很慢,在500Mhz的处理器上,ollydbg每秒最多可以跟踪2500到5000条指令,要加速跟踪,可以标记代码中一次执行的准线性块
为了让你熟悉跟踪过程我们试着调试一个简单的命令行程序
#include <stdio.h>
void f1(void) { printf("a"); };
void f2(void) { printf("b"); };
void f3(void) { printf("c"); };
void (*f[3])() = { f1,f2,f3 };
void main(void) {
int i,j,k;
for (i=0; i<100; i++) {
for (j=0; j<1000000; j++) ; // Long code k=i/33;
if (k>3) continue;
f[k](); // Here error (when i==99)!
}; printf("\n");
};
函数f1 f2 f3打印字母a b c,主程序调用每个函数33次,然后打印出新行和结束符,至少理论上是这样(你可能已经看出来哪里错了对吗?PS没看出来的打屁屁)好,我们学一下如何使用运行跟踪产生相同的错误结果。打开编译的程序,几秒后他崩溃了。
不,肯定哪里错了,ollydbg是你的实时调试器,选择调试但是反汇编窗口是空的,地址0062001指向空,你一点也不知道哪个命令跳转到这里,我们试着从头开始,Ctrl+F2,然后Ctrl+F11,等待几分钟,命令行仍然是空,可能一些代码花费了太长时间执行?F12暂停跟踪。在可执行模块里选择查看跟踪文件。
00401191地址处的一系列命令执行了24000次以上,转到该地址
一个3命令循环执行了1000000次,每秒5000个命令,ollydbg需要10分钟跟踪这个循环。注意,命令序列是准线性的,且没有跳到外面,在弹出的菜单选择“运行跟踪|跳过选择当追踪” 第四列的红线表示在跟踪时排除的命令,当ollydbg遇到排除序列,它会在该块之后设置临时断点,当然,任何返回或者跳转到外面都会使跟踪无效,因此ollydbg会检查这段代码并且要求你确认。继续跟踪,这次很快,20s,ollydbg就报告错误
确认了错误以后,打开跟踪窗口,
我们现在看到跳转到006210061的是004011AF处的指令CALL EAX,非法地址在调用前已经计算出,双击这一行以便在反汇编器中查看。寄存器和信息都是灰色的,说明他们都不是实际值,
0040A128的地址指向一个包括3个函数指针f1 f2 f3的数组,当这个命令执行最后一次,eax里面是3,已经超出数组边界,前2个命令应该执行边界检查,但是条件是非法的:当eax>3时跳出 正常的条件应该是>= 双击错误行,更正条件
在你输入了新的指令后,指令变红,表明指令经过修改,再次选中在弹出菜单选择“复制到可执行文件”,这样你的修改就写入文件了
你所需要的是保存修改的exe,这时exe运行正常,很简单对吗
教程2:加载dll
ollydbg可以调试单独的dll,windows不能直接运行dll,因此ollydbg用一个小程序loaddll.exe打开他们。如果你调试dll,ollydbg会自动解压loaddll.exe并链接库作为参数运行。
有了loaddll,你可以调用调试库输出的函数,我会用MessageBox和wsprintf解释这一用法
例一 MessageBox
1.加载dll 我们当然选是,ollydbg启动Loaddll,加载库然后暂停在主窗口循环处,这个地址标记为Firstbp,然后ollydbg分析dll显示他的代码
注意windows将dll加载到内存后会自动执行dll启动代码
2.从主菜单里选择“Debug|Call DLL export”,显示的对话框是非模态的,因此你仍然可以使用ollydbg其他功能。你可以打开代码和数据,设置断点,修改内存等。
3.选择你想调用的函数, MessageBox这个名字是通用的,事实上有MessageBoxA和MessageBoxW之分,我们分析第二个。我们选好以后分析器判断出函数以ret 10结束
4.设置堆栈参数数量。在这里不是必需的,因为ollydbg已经知道参数数量了
5.填写参数列表。这个对话框支持多达10个栈参数,参数是任何不适用寄存器的合法表达式。除此之外对话框有2个伪变量,loaddll.exe创建的父窗口句柄Hwnd和loaddll的实例句柄Hinst.为了方便当你第一次使用call export,ollydbg将他们加入历史列表
6.设置寄存器变量。寄存器变量在输出函数中很少使用。
7.选项设置。调用隐藏意味着当函数执行时对话框会隐藏。当函数调用结束,ollydbg会再次打开Call export,调用暂停指的是调试程序执行以后会被暂停运行。如果没什么错误的话,对话框会是这样:
8.通过按下call调用函数。ollydbg自动备份所有转储,验证和计算参数和寄存器,从屏幕移除对话框,然后调用MessageBoxW,会出现如下对话框:
好了,按ok,MessageBoxW会返回,Call export报告成功,注意返回的eax是1,正好是IDOK的数字值,很简单,不是吗?
细节与资源
loaddll.exe是一个压缩的汇编写的win32程序。看看他的源码:
- This is the full code of loaddll.exe. It can be compiled using Borland's TASM32 with following commands:
- tasm32 -mx -zi -m5 loaddll.asm,,loaddll.lst
- tlink32 -v- -c -S:40000 -B:400000 -Tpe -aa -m loaddll,,,import32.lib
- brc32 loaddll.rc -feloaddll.exe
- LOADDLL.ASM:
- P586 ; 32-bit instructions used!
- MODEL FLAT,PASCAL
- IDEAL ; I really like it!
- LOCALS
- PUBLICDLL WndProc,Firstbp,Prepatch,CallDLL,Finished;
- PUBLICDLL Patcharea,Endpatch
- PUBLICDLL Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10
- SEGMENT _DATA1 PARA PUBLIC USE32 'DATA'
- ; Text below is a keyphrase used by OllyDbg to verify that LoadDll
- ; is correct. Loads at fixed address 00420000. Never change! Note
- ; how coward I am: you cannot replace copyright, otherwise this code
- ; will not work!
- DB "DLL Loader (C) 2004 Oleh Yuschuk"
- ; Link area. Never change the meaning or order of next 32 dwords!
- ERRMSG DD 0 ; Pointer to error
- HINST DD 0 ; Process instance
- HWND DD 0 ; Handle of main window
- DLLBASE DD 0 ; Base address of loaded DLL or NULL
- DD OFFSET Firstbp ; Address of first breakpoint
- DD OFFSET Prepatch ; Address of patch area before call
- DD OFFSET Arg1 ; Base of 10 arguments x 1024 bytes
- DD OFFSET Finished ; Address of breakpoint after call
- DUMMY DD 4 DUP(0) ; Reserved for the future
- PROCADR DD 0 ; Address of procedure, starts execution
- REGEAX DD 0 ; Register arguments
- REGECX DD 0
- REGEDX DD 0
- REGEBX DD 0
- REGESI DD 0
- REGEDI DD 0
- NARG DD 0 ; Number of arguments to push on stack
- ARGLIST DD 10 DUP(0) ; DLL argument list
- ESPDIFF DD 0 ; Difference in ESP caused by code
- DD 0 ; Reserved for the future
- WCLASS = THIS DWORD ; Hand-made WNDCLASS structure
- DD 0000002Bh ; CS_HREDRAW|VREDRAW|DBLCLKS|OWNDC
- DD WndProc ; Window procedure
- DD 0 ; Class extra bytes
- DD 0 ; Window extra bytes
- WCINST DD 0 ; Instance
- WCICON DD 0 ; Icon
- HCURS DD 0 ; Cursor
- HBGND DD 0 ; Background brush
- DD 0 ; No menu
- DD CLSNAME ; Class name
- MSG = THIS DWORD ; Hand-made MSG structure
- DD 0 ; Handle of window
- MSGID DD 0 ; Message ID
- DD 0 ; wParam
- DD 0 ; lParam
- DD 0 ; Timestamp
- DD 0 ; X coordinate
- DD 0 ; Y coordinate
- PSTRUCT = THIS DWORD ; Hand-made PAINTSTRUCT structure
- DD 0 ; HDC
- DD 0 ; fErase
- DD 0 ; rcPaint.left
- DD 0 ; rcPaint.top
- DD 0 ; rcPaint.right
- DD 0 ; rcPaint.bottom
- DD 0 ; fRestore
- DD 0 ; fIncUpdate
- DB 32 DUP(0) ; rgbReserved
- ORIGESP DD 0 ; Original ESP before call
- ORIGEBP DD 0 ; Original EBP before call
- EXPESP DD 0 ; Expected ESP after call (C)
- WNDNAME DB "OllyDbg DLL Loader",0
- CLSNAME DB "LoadDLLClass",0
- ICONAME DB "MAINICON",0 ; Green smashed bug - igitt!
- E_NONAM DB "Missing DLL name",0 ; Error notifications to OllyDbg
- E_NODLL DB "Unable to load DLL",0
- E_NPARM DB "Too many parameters",0
- ALIGN 16
- Arg1 DB 1024 DUP (?) ; Area for 10 memory arguments, 1 k each
- Arg2 DB 1024 DUP (?)
- Arg3 DB 1024 DUP (?)
- Arg4 DB 1024 DUP (?)
- Arg5 DB 1024 DUP (?)
- Arg6 DB 1024 DUP (?)
- Arg7 DB 1024 DUP (?)
- Arg8 DB 1024 DUP (?)
- Arg9 DB 1024 DUP (?)
- Arg10 DB 1024 DUP (?)
- ENDS _DATA1
- SEGMENT _TEXT1 PARA PUBLIC USE32 'CODE'
- EXTRN GetModuleHandleA: PROC
- EXTRN GetCommandLineA: PROC
- EXTRN LoadIconA: PROC
- EXTRN LoadCursorA: PROC
- EXTRN GetStockObject: PROC
- EXTRN RegisterClassA: PROC
- EXTRN CreateWindowExA: PROC
- EXTRN DestroyWindow: PROC
- EXTRN PostQuitMessage: PROC
- EXTRN ShowWindow: PROC
- EXTRN Sleep: PROC
- EXTRN BeginPaint: PROC
- EXTRN EndPaint: PROC
- EXTRN DefWindowProcA: PROC
- EXTRN LoadLibraryA: PROC
- EXTRN PeekMessageA: PROC
- EXTRN TranslateMessage: PROC
- EXTRN DispatchMessageA: PROC
- EXTRN ExitProcess: PROC
- ; Window procedure of main LoadDLL window.
- PROC WndProc
- ARG LP:DWORD,WP:DWORD,MS:DWORD,HW:DWORD
- PUSH EDX
- PUSH EDI
- PUSH ESI
- MOV EAX,[MS]
- CMP EAX,0001h ; WM_CREATE
- JE RET0
- CMP EAX,0002h ; WM_DESTROY
- JNE @@080
- PUSH 0
- CALL PostQuitMessage
- JMP RET0
- @@080: CMP EAX,000Fh ; WM_PAINT
- JNE @@100
- PUSH OFFSET PSTRUCT
- PUSH [HW]
- CALL BeginPaint
- PUSH OFFSET PSTRUCT
- PUSH [HW]
- CALL EndPaint
- JMP RET0
- @@100: CMP EAX,0010h ; WM_CLOSE
- JNE @@200
- PUSH [HW]
- CALL DestroyWindow
- JMP RET0
- @@200: ; None of listed above, pass to DefWindowProc().
- PUSH [LP]
- PUSH [WP]
- PUSH [MS]
- PUSH [HW]
- CALL DefWindowProcA
- JMP RETA
- RET0: XOR EAX,EAX
- JMP SHORT RETA
- RET1: MOV EAX,1
- RETA: POP ESI
- POP EDI
- POP EDX
- RET
- ENDP WndProc
- START: MOV EBP,ESP ; Here execution begins
- PUSH 0
- CALL GetModuleHandleA
- MOV [DWORD DS:WCINST],EAX
- MOV [DWORD DS:HINST],EAX
- CALL GetCommandLineA ; Path to LOADDLL is taken into quotes
- MOV ESI,EAX
- INC ESI ; Skip first quote
- @@10: MOV AL,[BYTE DS:ESI] ; Skip path to LOADDLL.EXE
- INC ESI
- OR AL,AL
- JNE @@12
- MOV [DWORD DS:ERRMSG],OFFSET E_NONAM
- JMP ERROR
- @@12: CMP AL,'"'
- JNE @@10
- @@20: MOV AL,[BYTE DS:ESI] ; Skip spaces
- CMP AL,' '
- JNE @@30
- INC ESI
- JMP SHORT @@20
- @@30: PUSH ESI
- CALL LoadLibraryA ; Load DLL
- OR EAX,EAX
- JNE @@32
- MOV [DWORD DS:ERRMSG],OFFSET E_NODLL
- JMP ERROR
- @@32: MOV [DWORD DS:DLLBASE],EAX
- PUSH OFFSET ICONAME
- PUSH [DWORD DS:HINST]
- CALL LoadIconA
- MOV [DWORD DS:WCICON],EAX
- PUSH 7F88h ; IDC_NO
- PUSH 0 ; External resource
- CALL LoadCursorA
- MOV [DWORD DS:HCURS],EAX
- PUSH 0 ; WHITE_BRUSH
- CALL GetStockObject
- MOV [DWORD DS:HBGND],EAX
- PUSH OFFSET WCLASS
- CALL RegisterClassA
- PUSH 0 ; Parameters: none
- PUSH [DWORD DS:HINST] ; Instance
- PUSH 0 ; Menu: none
- PUSH 0 ; Parent window: none
- PUSH 100 ; Width
- PUSH 200 ; Height
- PUSH 80000000h ; CW_USEDEFAULT
- PUSH 80000000h ; CW_USEDEFAULT
- PUSH 10CF0000h ; WS_OVERLAPPEDWINDOW|WS_VISIBLE
- PUSH OFFSET WNDNAME ; Window name
- PUSH OFFSET CLSNAME ; Class name
- PUSH 0 ; Extended style: none
- CALL CreateWindowExA
- MOV [DWORD DS:HWND],EAX ; Save handle
- PUSH 9 ; SW_RESTORE
- PUSH EAX
- CALL ShowWindow
- Firstbp: NOP ; First breakpoint is set here
- WINLOOP: CMP [DWORD DS:PROCADR],0 ; Request to call some function?
- JE NOCALL
- MOV [DWORD DS:ORIGESP],ESP
- MOV [DWORD DS:ORIGEBP],ESP
- PUSH 0 ; Security buffer (16 doublewords)
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- PUSH 0
- MOV ECX,[DWORD DS:NARG]
- JECXZ @@44
- CMP ECX,10
- JBE @@40
- MOV [DWORD DS:ERRMSG],OFFSET E_NPARM
- JMP ERROR
- @@40: MOV EAX,OFFSET ARGLIST
- @@42: PUSH [DWORD EAX] ; Push requested number of arguments
- ADD EAX,4
- LOOP @@42
- @@44: MOV [DWORD DS:EXPESP],ESP ; Expected ESP after return (C)
- MOV EAX,[DWORD DS:REGEAX] ; Preset registers
- MOV ECX,[DWORD DS:REGECX]
- MOV EDX,[DWORD DS:REGEDX]
- MOV EBX,[DWORD DS:REGEBX]
- MOV ESI,[DWORD DS:REGESI]
- MOV EDI,[DWORD DS:REGEDI]
- Prepatch: NOP ; Patch area before call
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- CallDLL: CALL [DWORD DS:PROCADR] ; Call DLL function
- NOP ; Patch area after call
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- MOV [DWORD DS:REGEAX],EAX ; Get modified registers
- MOV [DWORD DS:REGECX],ECX
- MOV [DWORD DS:REGEDX],EDX
- MOV [DWORD DS:REGEBX],EBX
- MOV [DWORD DS:REGESI],ESI
- MOV [DWORD DS:REGEDI],EDI
- MOV EAX,ESP
- SUB EAX,[DWORD DS:EXPESP]
- MOV [DWORD DS:ESPDIFF],EAX
- MOV EBP,[DWORD DS:ORIGEBP]
- MOV ESP,[DWORD DS:ORIGESP]
- MOV [DWORD DS:PROCADR],0 ; Confirm execution
- NOP
- Finished: INT 3 ; Pause after execution
- NOP
- NOCALL: PUSH 0
- CALL Sleep ; Be fair to other applications
- PUSH 1 ; PM_REMOVE
- PUSH 0 ; Process all messages
- PUSH 0
- PUSH 0 ; Any window
- PUSH OFFSET MSG
- CALL PeekMessageA
- OR EAX,EAX
- JZ WINLOOP
- PUSH OFFSET MSG
- CALL TranslateMessage
- PUSH OFFSET MSG
- CALL DispatchMessageA
- MOV EAX,[DWORD DS:MSGID]
- CMP EAX,12h ; WM_QUIT
- JNE WINLOOP
- PUSH 0
- CALL ExitProcess ; Hasta la vista!
- ERROR: PUSH 00001001h ; Special return code, means error
- CALL ExitProcess ; Error detected
- ALIGN 4
- Patcharea: DB 2047 DUP(90h) ; Big patch area (2 K of NOPs)
- Endpatch: NOP
- ENDS _TEXT1
- END START
- LOADDLL.RC:
- MAINICON ICON // Green bug
- {
- '00 00 01 00 02 00 20 20 10 00 00 00 00 00 E8 02'
- '00 00 26 00 00 00 10 10 10 00 00 00 00 00 28 01'
- '00 00 0E 03 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 04 00 00 00 00 00 80 02 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
- '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
- 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
- '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 02 A0 00 00 00 00 A2 00 00 00 00 00'
- '00 00 00 00 0A 20 00 00 00 0A 2A 2A 00 00 00 00'
- '00 00 00 00 A2 A2 00 00 00 A2 A2 A2 00 00 00 00'
- '00 00 00 00 2A 2A 00 00 0A 2A 2A 2A 00 00 00 00'
- '00 00 00 00 A2 A2 00 00 A2 A2 A2 A0 00 00 00 00'
- '00 00 00 00 2A 2A 00 0A 2A 2A 2A 20 00 00 02 A2'
- '00 00 00 00 02 A2 A0 A2 A2 A2 A2 00 00 00 0A 2A'
- '2A 2A 00 00 0A 2A 2A 2A 2A 2A 20 00 00 00 02 A2'
- 'A2 A2 A0 00 02 A2 A2 A2 A2 A2 00 00 00 00 0A 2A'
- '2A 2A 2A 2A 2A 2A 2A 2A 2A 00 00 00 00 00 00 A2'
- 'A2 A2 A2 A2 A2 A2 A2 A2 00 00 00 00 00 00 00 00'
- '2A 2A 2A 2A 2A 2A 2A 2A 00 00 00 00 00 00 00 00'
- '00 02 A2 A2 A2 A2 A2 A2 00 00 00 00 00 00 00 00'
- '00 00 0A 2A 2A 2A 2A 2A 2A 00 00 00 00 00 00 00'
- '00 00 02 A2 A2 A2 A2 A2 A2 A2 A2 00 00 00 00 00'
- '00 00 0A 2A 2A 2A 2A 2A 2A 2A 2A 20 00 00 00 00'
- '00 00 02 A2 A2 A2 A2 A2 A2 A2 A2 A2 A2 00 00 00'
- '00 00 0A 2A 2A 2A 2A 2A 00 00 2A 2A 2A 20 00 00'
- '00 00 A2 A2 A0 A2 A2 A0 00 00 02 A2 A2 A0 00 00'
- '00 00 2A 2A 00 0A 2A 20 00 00 00 2A 2A 20 00 00'
- '00 00 00 00 00 00 A2 A0 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 2A 20 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 A2 A0 00 00 00 00 00 00 00 00'
- '00 2A 20 00 00 00 2A 2A 00 00 00 00 00 00 00 00'
- 'A2 A2 A0 00 00 00 A2 A2 00 00 00 00 00 00 00 00'
- '2A 2A 20 00 00 00 2A 2A 00 00 00 00 00 00 00 00'
- 'A2 A2 A0 00 00 00 02 A2 00 00 00 00 00 00 00 0A'
- '2A 2A 20 00 00 00 0A 2A 00 00 00 00 00 00 00 02'
- 'A2 A2 00 00 00 00 00 00 00 00 00 00 00 00 00 0A'
- '2A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF F9'
- 'FF 3F FF F0 FE 0F FF F0 FC 07 FF E0 78 07 FF E0'
- '70 07 FF E0 60 0F 8F E0 40 0F 00 F0 00 1F 00 70'
- '00 3F 00 10 00 7F 00 00 00 FF 80 00 03 FF C0 00'
- '0F FF E0 00 03 FF FC 00 00 3F FF 00 00 1F FF 00'
- '00 03 FF 00 00 01 FF 00 00 00 FE 00 0F 00 FE 04'
- '0F 80 FF 0E 0F C1 FF FE 0F FF FC 7E 0F FF F0 3E'
- '07 FF E0 3E 07 FF E0 3E 07 FF C0 3F 07 FF C0 3F'
- '07 FF C0 7F 0F FF C0 FF FF FF E3 FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
- '00 00 C0 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
- '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
- '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
- '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
- '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
- '00 AA 00 0A AA 00 00 00 00 AA 00 AA AA 00 00 00'
- '00 AA 0A AA A0 00 0A AA 00 0A AA AA 00 00 0A AA'
- 'AA AA AA 00 00 00 00 0A AA AA AA 00 00 00 00 00'
- '0A AA AA A0 00 00 00 00 0A AA AA AA AA 00 00 00'
- 'AA AA AA 00 AA A0 00 00 00 00 A0 00 00 00 00 00'
- '00 00 A0 00 00 00 00 0A 00 00 AA 00 00 00 00 AA'
- '00 00 AA 00 00 00 00 AA 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FC E3 00 00 F8 41 00 00 F8 01'
- '00 00 88 03 00 00 00 07 00 00 00 0F 00 00 80 1F'
- '00 00 E0 03 00 00 F0 01 00 00 E0 00 00 00 F0 31'
- '00 00 EE 3F 00 00 86 1F 00 00 86 1F 00 00 87 3F'
- '00 00 8F FF 00 00'
- }
复制代码
从START开始执行,loaddll获取命令行,跳过可执行文件名(必须有双引号),解析dll路径将其传给loadlibrary,一旦出错,就会将错误信息指针放到固定位置,以0x1001退出码退出,成功后创建一个小窗口,然后暂停在Firstbp,这个断点是ollydbg启动时设置的。所有和ollydbg的通信都是通过128字节内存区,这个区域必须从0x420020开始,该处刚好位于关键区域之后。前几个数据包含loaddll.exe的地址,用于ollydbg设置断点和参数。接着是函数调用地址,寄存器内容,参数个数,参数。当loaddll执行到windows消息循环时,它会不断检查输出函数的地址是否非0,如果是,loaddll保存ESP和EBP,将16个0压栈。这样能避免用户指定无效参数个数。然后他会将参数和寄存器压栈,在Prepatch地址有16个NOP用于打补丁。如果你需要更多空间,可以调到Patcharea 2K字节长的地方。注意到Ollydbg在存在同名文件时不解析loaddll.exe 当CallDLL输出函数被调用时,该指令之后会有16个NOP,调用之后程序保存修改的寄存器和ESP偏移。如果提供的参数个数非法,ollydbg会报告错误。最终loaddll存储esp和ebp,清空PROCADR,断在Finished的INT3处,当执行到这里,ollydbg知道直接完毕。
Loaddll.asm是自由软件,不过不要使用loaddll.rc的绿虫子图标!
|
|