TA的每日心情 | 开心 2021-8-30 00:00 |
---|
签到天数: 35 天 [LV.5]常住居民I
|
楼主 |
发表于 2006-12-12 16:39:12
|
显示全部楼层
?父窗口句柄。 这里我们选择<Hwnd> ;handle of owner window. Here, we simply select <Hwnd>;
?在消息框中UNICODE文本的地址。选择Arg2并按回车。缓冲区窗口会以16进制的格式显现内存中的缓冲区。这个缓冲区初始化全是0。点击第一个字节,并按快捷键
Ctrl+E(另外, 也可以从菜单中选择“二进制[Binary]|编辑[Edit]”)。这时会出现一个对话框,在对话框中键入“Text in box”或者其他希望显示的字符串;
?消息框标题的UNICODE文本的地址。选择Arg3并在Unicode格式的内存中写上“Box title”;
?消息框的风格。使用常量MB_xxx进行组合.OllyDbg 可以识别这些常量。在这里我们键入:MB_OK|MB_ICONEXCLAMATION。
这里不需要寄存器参数。
现在我们准备调用输出函数。选项“在调用时隐藏[Hide on call]”意思是说,当函数运行时对话框将会从屏幕消失。当我们执行一个会运行很长时间的函数,或者设置了断点的时候,这个选项非常的有用。您也可以手动关闭对话框。当函数执行完毕后,OllyDbg会重新自动打开。“调用输出函数”对话框。选项“在调用后暂停[Pause after call]”意思是说,在执行完函数后,loaddll将会被暂停。
按“调用[Call]按钮”后,OllyDbg 会自动备份所有的内存、校验、参数、寄存器等信息。并隐藏对话框,然后调用 MessageBoxW 函数。和期望的一样,消息框在屏幕中出现了:
函数 MessageBoxW 不会修改参数。如果您调用的函数更新了内存,比如函数 GetWindowName,修改的字节将会在数据区里高亮。注意:EAX 返回值为1,表示成功。
其他的例子请访问我的网站:
http://home.t-online.de/home/Ollydbg/Loaddll.htm.
不幸的是,您不能通过这种方式调试OllyDbg的插件,插件关联到ollydbg.exe文件,Windows系统不能在同一个应用程序里加载并运行两个可执行文件。
解码提示[Decoding hints]
在某些情况下,分析器不能区分代码和数据。让我们看看下面的例子:
const char s[11] = "0123456789";
...
for (i=0x30; i<0x3a; i++) t[i-0x30]=s[i-0x30];
好的编译器将会将上面的代码优化成如下样子: e
for (i=0x30; i<0x3a; i++) (t-0x30)=(s-0x30);
这里t-0x30 和 s-0x30 都是常量,并编译成如下形式:
MOV AL,[BYTE s_minus_30+EBX]
MOV [BYTE t_minus_30+EBX],AL
编译器也可能将常量字符串"0123456789"插入到执行代码中。在1.10版本中,我打算用寄存器的值来决定是否的数据或代码。当遇到上面的命令,分析器将假定地址
s_minus_30处包含字符数据。但事实上,可能那里是代码。
万一出现上述问题,我们应该怎么办呢?有两种办法:最快最笨的办法是:将分析错误的部分删除(快捷键:退格键),这样OllyDbg将使用默认的反汇编器进行解码。
更好的办法是使用解码提示[decoding hints]。您可以告诉OllyDbg如何解释选中的内存内容。这种方法在重新分析(Ctrl+A)时,解释依然有效。
设置提示的方法:在反汇编窗口中,选中需要修正提示的代码或数据,然后在快捷菜单中选择 分析[Analysis]|在下次分析时,将选择部分视为[During next analysis, treat selection as]。选择以下选项之一:
命令[Command] - 第一个被选中的字节开始的有效命令。这条命令,还有所有后面的部分,直到有Jump或Return命令出现,以及含有Jump或Call命令所到达位置的部分,都会被视为命令;
字节[Byte],
字[Word],
双字[Doubleword] - 选中的前1、2、4字节视为对应大小的数据;
所有选中命令[Commands] - 全部选中部分(直到第一个无效命令)和可以到达由有效命令集组成的目的地址;
字节[Bytes],
字[Words],
双字[Doublewords], - 全部选中部分以1、2、或 4字节分组;
ASCII字符串[ASCII text],
UNICODE字符串[UNICODE text] - 全部选中部分为ASCII 或 UNICODE 字符串;
默认(移除提示)[Default (remove hints)] - 从选中部分中移除全面提示;
移除全部提示[Remove all hints] - 从全部模块中移除解码提示。
OllyDbg 保存提示到.udd文件中。
表达式赋值[Evaluation of expressions]
[code]
OllyDbg能够支持非常复杂的表达式。表达式的语法格式将在这个主题的后面进行介绍,但我想您对此不一定真的感兴趣。那么我先举几个实例来说明:
10 - 常量 0x10 (无符号)。所有整数常量都认为是十六进制的,除非后面跟了点;
10. - 十进制常量10(带符号);
'A' - 字符常量 0x41;
EAX - 寄存器EAX的内容,解释为无符号数;
EAX. -寄存器EAX的内容,解释为带符号数;
[123456] - 在地址123456处的无符号双字内容。默认情况,OllyDbg假定是双字长操作数;
DWORD PTR [123456] - 同上。关键字 PTR 可选;
[SIGNED BYTE 123456] - 在地址123456处带符号单字节。OllyDbg支持类MASM和类IDEAL两种内存表达式;
STRING [123456] - 以地址123456作为开始,以零作为结尾的ASCII字符串。中括号是必须的,因为您要显示内存的内容;
[[123456]] - 在地址123456处存储的双字所指向的地址内的双字内容;
2+3*4 - 值为14。OllyDbg 按标准C语言的优先级进行算术运行;
(2+3)*4 - 值为20。使用括号改变运算顺序。
EAX.<0. - 如果EAX在0到0x7FFFFFFF之间,则值为0,否则值为1。注意0也是有符号的。当带符号数与无符号数比较时,OllyDbg会将带符号数转成无符号数。
EAX<0 - 总为0(假),因为无符号数永远是正的。
MSG==111 - 如果消息为WM_COMMAND,则为真。0x0111是命令 WM_COMMAND 的数值。MSG只能用于设置在进程消息函数的条件断点内。
[STRING 123456]=="Brown fox" - 如果从地址0x00123456开始的内存为ASCII字符串"Brown fox"、"BROWN FOX JUMPS"、 "brown fox???",或类似的串,那么其值为1。比较不区分大小写和文本长度。
EAX=="Brown fox" - 同上,EAX按指针对待。
UNICODE [EAX]=="Brown fox" - OllyDbg认为EAX是一个指向UNICODE串的指针,并将其转换为ASCII,然后与文本常量进行比较。
[ESP+8]==WM_PAINT - i在表达式中您可以使用上百种Windows API符号常量。
([BYTE ESI+DWORD DS:[450000+15*(EAX-1)]] & 0F0)!=0 - 这绝对是个有效的表达式。
现在我们介绍语法格式。在大括号({})内的每个元素都只能出现一次,括号内的元素顺序可以交换:
表达式 = 内存中间码|内存中间码<二元操作符>内存中间码
内存中间码 = 中间码| { 符号标志 大小标志 前缀} [表达式 ]
中间码 = (表达式)| 一元操作符 内存中间码 | 带符号寄存器 | 寄存器 | FPU寄存器 | 段寄存器 | 整型常量 | 浮点常量 | 串常量 | 参数 | 伪变量
一元操作符 = ! | ~ | + |
带符号寄存器 = 寄存器.
寄存器 = AL | BL | CL ... | AX | BX | CX ... | EAX | EBX | ECX ...
FPU寄存器 = ST | ST0 | ST1 ...
段寄存器 = CS | DS | ES | SS | FS | GS
整型常量 = <十进制常量>. | <十六进制常量> | <字符常量> | <API符号常量>
浮点常量 = <符点常量>
串常量 = "<串常量>"
符号标志 = SIGNED | UNSIGNED
大小标志 = BYTE | CHAR | WORD | SHORT | DWORD | LONG | QWORD | FLOAT | DOUBLE | FLOAT10 | STRING | UNICODE
前缀 = 中间码:
参数 = %A | %B // 仅允许在监察器[inspector] 中使用
伪变量 = MSG // 窗口消息中的代码
这个语法并不严格。在解释[WORD [EAX]]或类似的表达式时会产生歧义。可以理解为以寄存器EAX所指向地址的两字节内容为地址,所指向的双字内容;也可以理解为以寄存器EAX所指向地址的四字节内容为地址,所指向的两字节内容。而OllyDbg会将修饰符尽可能的放在地址最外面,所以在这种情况下,[WORD [EAX]] 等价于 WORD [[EAX]]。
默认情况下,BYTE、WORD 和 DWORD 都是无符号的,而CHAR、SHORT 和 LONG都是带符号的。也可以使用明确的修饰符SIGNED 或 UNSIGNED。例如在二元操作时,如果一个操作数是浮点的,那么另外一个就要转成浮点数;或者如果一个是无符号胆,那么另外一个要转成无符号的。浮点类型不支持UNSIGNED。大小修饰符后面跟 MASM兼容关键字PTR(如:BYTE PTR)也允许的,也可以不要PTR。寄存器名和大小修饰符不区分大小写。
您可以使用下面类C的运算符(0级最高):
优先级 类型 运算符
0 一元运算符 ! ~ + -
1 乘除运算 * / %
2 加减运算 + -
3 位移动 << >>
4 比较 < <= > >=
5 比较 == !=
6 按位与 &
7 按位异或 ^
8 按位或 |
9 逻辑与 &&
10 逻辑或 ||
在计算时,中间结果以 DWORD 或 FLOAT10 形式保存。某些类型组合和操作是不允许的。例如:QWODRD 类型只能显示;STRING 和 UNICODE 只能进行加减操作(像C语言里的指针)以及与 STRING、UNICODE 类型或串常量进行比较操作;您不能按位移动浮点[FLOAT] 类型,等等。
自定义函数描述[Custom function descriptions]
概论[Introduction]
OllyDbg包含(做为内部资源)1900多种标准函数以及400多种标准C函数的名称和参数。分析器[Analyzer] 用这些描述使被调试程序更加易懂。比较下面一个例子,分析器的函数CreateFont:
PUSH OT.00469F2A ; ASCII "Times New Roman"
PUSH 12
PUSH 2
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
MOV EAX,DWORD PTR [49FA70]
PUSH EAX
PUSH 190
PUSH 0
PUSH 0
PUSH 0
PUSH 10
CALL <JMP.&GDI32.CreateFontA>
这是分析后的:
MOV EAX,DWORD PTR [49FA70]
PUSH OT.00469F2A ; ?FaceName = "Times New Roman"
PUSH 12 ; ?PitchAndFamily = VARIABLE_PITCH|FF_ROMAN
PUSH 2 ; ?Quality = PROOF_QUALITY
PUSH 0 ; ?ClipPrecision = CLIP_DEFAULT_PRECIS
PUSH 0 ; ?OutputPrecision = OUT_DEFAULT_PRECIS
PUSH 0 ; ?CharSet = ANSI_CHARSET
PUSH 0 ; ?StrikeOut = FALSE
PUSH 0 ; ?Underline = FALSE
PUSH EAX ; ?Italic => TRUE
PUSH 190 ; ?Weight = FW_NORMAL
PUSH 0 ; ?Orientation = 0
PUSH 0 ; ?Escapement = 0
PUSH 0 ; ?Width = 0
PUSH 10 ; ?Height = 10 (16.)
CALL <JMP.&GDI32.CreateFontA> ; ?CreateFontA
显然,后面的代码更容易理解。API函数CreateFont 有14个参数。分析器标记所有这些参数的名称并解码他们的值。如果寄存器跟踪开启,那么分析器同时会解码参数Italic
的值为地址49FA70处双字长的内容。解码使用参数的真实值,所以如果[49FA70]里的内容改变了,那么参数Italic的值也会随之改变。当EIP指向跳转或调用该函数的命令,或指向入口时,OllyDbg也会在栈中对已知函数的参数进行解码。
OllyDbg可以对像printf()这样参数个数可变的函数进行参数解码:
PUSH EAX ; ?<%.*s>
PUSH E8 ; ?<*> = E8 (232.)
PUSH EBX ; ?<%08X>
PUSH Mymodule.004801D2 ; ?format = "Size %08X (%.*s) bytes"
PUSH ESI ; ?s
CALL Mymodule.sprintf ; ?sprintf
您可以定义自己的函数。每次您打开某个应用程序时,OllyDbg都会重新设置函数参数表并用内嵌描述添充这个表。然后尝试打开文件“< OllyDbg目录>\common.arg”和“<OllyDbg目录>\<应用程序名>.arg”,这里<应用程序名>使用8.3格式(DOS)被调试程序文件名(不带路径和扩展名)。
下面看一个简单的.arg文件实例:
INFO Simple .ARG file that decodes CreateHatchBrush
TYPE HS_X
IF 0 "HS_HORIZONTAL"
IF 1 "HS_VERTICAL"
IF 2 "HS_FDIAGONAL"
IF 3 "HS_BDIAGONAL"
IF 4 "HS_CROSS"
IF 5 "HS_DIAGCROSS"
ELSEINT
END
TYPE COLORREF
IF 0 "<BLACK>"
IF 00FFFFFF "<WHITE>"
OTHERWISE
TEXT "RGB("
FIELD 000000FF
UINT
TEXT ","
FIELD 0000FF00
UINT
TEXT ","
FIELD 00FF0000
UINT
TEXT ")"
END
STDFUNC CreateHatchBrush
"style" HS_X
"colorref" COLORREF
END
标准Windos API函数CreateHatchBrush(int style,int colorref) 有两个参数。第一个必须是阴影风格[hatch style],第二个是常量由红色、绿色、蓝色组成,并用一个32
位整数的低三字节表示。为了解码这些参数,文件定义了两个新的参数类型:HS_X 和 COLORREF。
阴影风格是一个简单的枚举类型,如0表示HS_HORIZONTAL(水平风格)、1表示HS_VERTICAL(垂直风格)。IF关键字比较参数与第一个操作数(注意:其总是十六进制的),如果相同则显示第二个操作数里的文本。但万一匹配失败会如何?关键字ELSEINT 会然OllyDbg会将参数解释为一个整数。
COLORREF 更复杂一些。首先尝试解码两个广泛使用的颜色值:黑(全0组成)与白(全0xFF组成)。如果匹配失败,COLORREF尝试解码颜色为一个结构包含红、绿、蓝的亮度。FIELD会用第一个操作数与参数进行逻辑与操作。然后转换结果为整数,并同时按位右移第一个操作及该整数,直到第一个操作数的二进制个位数字为1,这时整数按位右移的结果以无符号10进制显示出来。这个例子做了三次这样的操作,以分离出每个颜色成份。TEXT关键字用于无条件显示文本。如果参数为00030201,那么
COLORREF将其解码为RGB(1.,2.,3.)。
大多断API函数都会从栈中移除参数并保护寄存器EBX, EBP, ESI 和 EDI。声明这样的函数为STDFUNC,以告诉分析器该函数做了这样的事情。否则请其描述为FUNCTION
。
万一某个参数由多个域及比特值组成,比如上面提到的fdwPitchAndFamily ,我们该怎么办?请看下面这个例子:
TYPE FF_PITCH
MASK 03
IF 00 "DEFAULT_PITCH"
IF 01 "FIXED_PITCH"
IF 02 "VARIABLE_PITCH"
ELSEHEX
TEXT "|"
MASK 0C
BIT 04 "4|"
BIT 08 "8|"
MASK FFFFFFF0
IF 00 "FF_DONTCARE"
IF 10 "FF_ROMAN"
IF 20 "FF_SWISS"
IF 30 "FF_MODERN"
IF 40 "FF_SCRIPT"
IF 50 "FF_DECORATIVE"
ELSEHEX
END
前两个比特位(第0和等1位)表示倾斜度,必须一起解码。我们使用 MASK 03 来提取这两个比特并通过IF序列来解码。增加了连接符“|”,分别提取第2和第3个比特位,并分别单独解码。最后提取剩余部分并进行解码。
OllyDbg 会移除生成串尾部的连接符“|”、空格、冒号、逗号、分号和等号。
目前版本的分析仅能够解码32位参数。如您不能解码双精度浮点或长双精度浮点的函数参数。
格式描述
自定义解码信息由函数描述和类型描述两部分组成。函数描述部分非常的简单:
FUNCTION|STDFUNC [模块名]函数名
<第一个参数的名称> <第一个参数的类型>
……
<最后一个参数的名称> <最后一个参数的类型>
END
如果函数从栈中移除参数并保护寄存器EBX, EBP, ESI 和 EDI,请使用关键字STDFUNC。大多少函数都遵循这样的规则。其他情况则声明为FUNCTION。模块(EXE 或 DLL)名是可选的。如果模块名被忽略,OllyDbg会对尝试匹配任何模块。模块名不区分大小写。
函数名称总是区分大小写的。有针对UNICODE的函数必须使用后缀 A 或 W 加以区分,比如SetWindowTextA.。
参数的顺序又C风格的参数使用惯例一致。而16位Windows和32位API函数也是按惯例使用。如果参数名由多个字组成,或者包含特殊字符,那么请将其用两个单引号引起来。与在C语言中一样,省略号(叄┦且桓鎏厥獾募锹加糜诒硎静问??靠杀洹K?匦朐诤??枋龅淖詈蟆?llyDbg不会尝试解码这样的参数。如果函数的参数为空,则按functionname(void)对待
OllyDbg 仅支持32位的参数。某些参数已经预定义好了:
INT 以十六进制和带符号整数两种格式显示值
UINT 以十六进制和无符号整数两种格式显示值
HEX 以十六进制格式显示值
BOOL TRUE 或 FALSE
CHAR ASCII 字符
WCHAR UNICODE 字符
FLOAT 32位浮点数
ERRCODE 系统错误代码(像由函数GetLastError()报告的)
ADDR, PTR 地址(特殊情况:NULL)
ASCII ASCII 串指针
UNICODE UNICODE 串指针
FORMAT 在类似函数printf()(不包括wscanfW()!)使用的 ASCII 格式串
WFORMAT 类似函数wsprintfW()(不包括scanf()!)使用的 UNICODE 格式串
RECT RECT(矩形)结构指针
MESSAGE MSG(ASCII 窗口消息)结构指针
WMESSAGE MSG(UNICODE 窗口消息)结构指针
HANDLE 句柄(特殊情况:NULL, ERROR_INVALID_HANDLE)
HWND 窗口句柄
HMODULE 模块句柄
RSRC_STRING 带索引的资源串
NULL, DUMMY 有参数,但解码时跳过了
您不能重定义预定义类型。自定义类型允许您将参数分离成几个域并分别解码。类型描述有以下几种格式:
TYPE 类型名
[TEXT "任何文本"]
[<域选择器>]
<域解码>
<域解码>
[TEXT "任何文本"]
[PURGE]
...
<域选择器>
<域解码>
<域解码>
[TEXT "任何文本"]
END
类型名的程度限制在16个字符以内。 OllyDbg会无条件将"任何文本"作为生成的解码。域选择器提取一部分参数用于解码。以下域选择器,可以用于提取域:
MASK 十六进制掩码 - 域等于参数同十六进制掩码按位与(AND)的结果。
FIELD 十六进制掩码 - 参数同十六进制掩码按位与(AND)的数值,然后OllyDbg同时按位右移掩码和计算的数值直到掩码的二进制个位为1,这时数值按位右移的结果就是域的值。例如参数0xC250, FIELD F0,得到的结果是5。
SIGFIELD 十六进制掩码 -参数同十六进制掩码按位与(AND)的数值,然后OllyDbg同时按位右移掩码和计算的数值直到掩码的二进制个位为1,这时数值按位右移的结果转成带符号32位数就是域的值。例如参数0xC250 ,SIGFIELD FF00,得到的结果是0xFFFFFFC2。
简单域的解码会一次显示整个域的内容:
HEX - 以十六进制形式显示域内容;
INT - 以带符号十进制形式显示域内容(带小数点);
UINT -以无符号十进制形式显示域内容(带小数点);
CHAR - 以 ASCII 字符形式显示域内容。
域若是一个枚举类型,则可以使用IF序列,如果必要的话还可以在IF序列后跟关键字 TRYxxx 与 ELSExxx:
IF 十六进制值 "文本" - 如果域等于十六进制值,则将文本作为输出字符串;
TRYASCII - 如果域是一个指向ASCII串的指针,则显示这个串;
TRYUNICODE - 如果域是一个指向UNICODE串的指针,则显示这个串;
TRYORDINAL - 如果域是一序号(有16位均为0),则会显示为序号(“#”后跟整数);
OTHERWISE - 如果前面IF语句为真,则停止解码,否则继续解码;
ELSEINT - 如果前面所有的 IF 和 TRYxxx 语句均失败,则以带符号十进制数形式(带小数点)显示这个域;
ELSEHEX -如果前面所有的 IF 和 TRYxxx 语句均为失败,则以十六进制形式显示这个域;
ELSECHAR -如果前面所有的 IF 和 TRYxxx 语句均为失败,则以 ASCII 字符形式显示这个域;
ELSEWCHAR -如果前面所有的 IF 和 TRYxxx 语句均为失败,则以 UNICODE 字符形式显示这个域。
如果域是一个二进制位集,则可以使用BIT序列,如果必要的话可以后面跟关键字 BITZ 与 BITHEX :
BIT 十六进制掩码 "文本" - 如果值与十六进制掩码按位与(AND)的结果不是0,则将文本做为输出串;
BITZ十六进制掩码 "文本" - 如果值与十六进制掩码按位与(AND)的结果是0,则将文本做为输出串;
BITHEX十六进制掩码 - 如果值与十六进制掩码按位与(AND)的结果不是0,则将结果以十六进制形式显示。
特殊关键字 PURGE 会从输出串尾部移除以下几种符号:
空格 ' '
逗号 ','
或 '|'
冒号 ':'
等于 '='
这会让某些解码情况变的简单。关键字END是类型定义结尾标记并会自动运行PURGE命令。
预编译类型
OllyDbg在预编译资源时,已经包含150多种类型描述。以下列出了一部分。您可以在自定义文件中直接使用这些类型:
LANG_X - 操作系统语言ID(0 - 未知、 9 - 语言、 C - 法语,等等)
GENERIC_X - 访问类型(GENERIC_READ, GENERIC_WRITE...)
FILE_SHARE_X - 共享类型(FILE_SHARE_READ, FILE_SHARE_WRITE)
CREATEFILE_X - 文件创建模式(CREATE_NEW, OPEN_EXISTING...)
FILE_ATTRIBUTE_X - 文件属性(READONLY, SYSTEM, DELETE_ON_CLOSE...)
RT_AXX - 资源类型(RT_CURSOR, RT_GROUP_ICON, ASCII string...)
RT_WXX - 资源类型(RT_CURSOR, RT_GROUP_ICON, UNICODE string...)
COORD - 坐标结构 "(X=xxx,Y=yyy)"
STD_IO_X - 标准句柄(STD_INPUT_HANDLE, STD_ERROR_HANDLE...)
GMEM_X - 全局内存类型(GMEM_FIXED, GPTR...)
LMEM_X - 局部内存类型(LMEM_FIXED, LPTR...)
FSEEK_X - 文件查找类型(FILE_BEGIN, FILE_CURRENT...)
OF_X - 文件模式(fOF_READ, OF_SHARE_COMPAT, OF_VERIFY...)
O_X - 文件创建模式(O_RDONLY, O_BINARY, SH_COMPAT...)
SEMAPHORE_X - 信号量类型(SEMAPHORE_ALL_ACCESS, SYNCHRONIZE...)
SLEEP_TIMEOUT - 超时(INFINITE 或时间)
ROP - 一些标准柵格运算标志代码(ROP)(SRCCOPY, MERGEPAINT...)
COLORREF - RGB 颜色值("<WHITE>", "RGB(rr.,gg.,bb.)"...)
WS_X - 窗口风格(WS_OVERLAPPED, WS_POPUP...)
WS_EX_X - 扩展窗口风格(WS_EX_DLGMODALFRAME, WS_EX_TOPMOST...)
MF_X - 菜单标志(MF_BYPOSITION, MF_ENABLED...)
WM_X - ASCII窗口消息类型(WM_CREATE, WM_KILLFOCUS, CB_SETCURSEL...)
WM_W - UNICODE窗口消息类型(WM_CREATE, WM_KILLFOCUS, CB_SETCURSEL...)
VK_X - 虚拟键盘代码(VK_LBUTTON, VK_TAB, VK_F10...)
MB_X - message box style (MB_OK, MB_ICONHAND...)
HKEY_X - 预定义注册表句柄(HKEY_CLASSES_ROOT, HKEY_LOCAL_MACHINE...)
还有更多的预编译类型。如果常量在它文件被定义为ABC_ xxxxxxxx,那么一般就有ABC_X预编译类型。
注意:
1.如果OllyDbg是即时调试器,并且在Windows 95下挂接执行了DebugBreak() 的应用程序,则这个应用程序在挂接后,还会运行。在基于NT的系统下,应用程序应该会在
DebugBreak()暂停。
2. 命令 SMSW (保存机器状态字[Store Machine Status Word])。 这个命令仅接受寄存器 AX 作为参数,而程序编译成EAX接受参数。 |
|