IDA经典教程

更新时间:2024-03-31 00:54:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

IDA简易教程

作者:www.datarescue.com

mailto:winroot@126.com

2004-11-20 初步翻译完成,希望大家指正错误,谢谢!

我的鸟语太差大概翻译了一下,大家凑合着能看懂就行了:-)有些地方用自己理解的意思改写了一下!

本文的主要内容就是讲如何用IDA来辅助识别各种类型的数据. 版权信息:所有版权归原文作者所有,如许转载清保持文章完整性。 索引

1 第一节:C语言的小程序 2 第二节:基本类型的识别 3 第三节:操作数格式

4 第四节:字符和字符串的操作 5 第五节:数组 6 第六节:枚举类型

7 第七节:Bit-fields(位域) 8 第八节:结构体

9 第九节:结构变量和结构数组

10 第十节:联合体和结构体中的结构体 11 第十一节:可变的结构体 12 第十二节:结构体偏移 13 第十三节:联合体偏移量 14 第十四节:地址偏移量 15 第十五节:最终逆向结果 附录

第一节:C语言的小程序

为了演示IDA的功能先写一段小程序。(代码在附录)程序在此 源代码 程序执行结果:

CUSTOMERS:

CUSTOMER 0001: Peter (m) CUSTOMER 0002: John (m) CUSTOMER 0003: Mary (f)

PRODUCTS:

PRODUCT 0001: BOOK: IDA QuickStart Guide

PRODUCT 0002: SOFTWARE: IDA Pro: PC; WINDOWS DOS; DISASSEMBLY PRODUCT 0003: SOFTWARE: PhotoRescue: PC MAC; WINDOWS OS-X; RECOVERY PRODUCT 0004: SOFTWARE: aCrypt: PC; WINDOWS; CRYPTOGRAPHY

TOP

----------------------------------------------------------------------

第二节:基本类型的识别

用IDA分析我们前面的程序,我们会发现下图的类型

只要按\我们就可以任意转换这些不确定的类型.可以变成byte,word,dword(db,dw,dd)。 当然你也可以设置更多的数据转换类型:

选择“Options”菜单的“Setup data types”命令就可以设置了

值得注意的是:你在数据转换的时候,它是依据数据自身的结构来转换的。我们按“D”的时候, 如果下一个字节已经被你转换过,你的本次转换,IDA将会提示让你确认。

注:如果你想改变这种默认设置可以在“Options”菜单“Convert already defined bytes”命令里设置

撤销你的所有转换按“U”键。

TOP ------------------------------------------------------------------------------------- 第三节:操作数格式

数据类型自定义转换后,被操作过的数据(就是你按过“D”的)的进制IDA也是可以自定义转变的,

通过在“Operands”工具栏的“Number”命令我们可以随意转换数字的进制

最下面的“Toggle leading point”就是填补数据前的空位为0(就是说如果当前数据未占满数据格式的所有位高位用0来填补)

IDA还可以转换数据的标志位(就是正负)具体操作如下图:

最后呢~~如果这些转换你还不满意(够BT)当然你还可以自定义数据进制如图:

TOP ----------------------------------------------------------------------------------------- 第四节:字符和字符串的操作

作者又说话了:很多程序都是包含字符串的,一些被操作过的数据(就是你按过“D”的)可以转化为

字符,使用的命令就在“Operands”工具栏上

由于编程语言的不同造成字符串也有不同的格式,当然IDA就支持所有的格式了。

IDA在转化后会在地址添加一个名字。因为我们的程序是c的所以就找到c的字符串。具体操作如图:

如果不是C写的程序怎么办呢?我们可以在“Options”菜单“ASCII string style”命令中设置。 允许你修改其它类型为默认设置,使用默认设置的快捷键是“A”,或者自定义一种类型可以使用不常用的终止字符。

TOP -------------------------------------------------------------------------- 第五节:数组

在c中,ASCII字符串被认为是字符数组,IDA是如何处理数组的呢?

我们用最常用命令来定义数组中的第一个元素,设置第一个元素类型为byte,格式为char,然后点击“*”号键(或者“Edition ”工具栏的“Array”命令)来创建数组。这时弹出一个对话框,可以设置很多变量。

你可以定义数组一行的显示个数,还可以使用“Element width”来设置他们之间的宽度。 使用“Use dup construct ”选项可以合并连贯的相似字节,“ Display index ”选项可以像注释一样显示数组的下标。

例如我们设置一个有64个元素的数组,一行有8个元素,每个元素之间的宽度为4,不选取“dup constructs”,选取“Display index ”,我们就可以得到下面的数组。

当IDA遇到未被识别的字节他会用红色的高亮显示。

当然你也可以选择一个范围来创建数组,IDA会自适应的设定。

TOP

------------------------------------------------------------------------------------ 第六节:枚举类型

还记得我们在C程序中定义的product_category_t 类型吗? 让我们用IDA的“Enumerations”来定义一下。

首先,我们打开“Enumerations”窗口来创建一个新的枚举类型

我们输入我们的枚举类型值

在check_product()函数,我们可以用枚举类型重新定义一些操作数。 右键点击在数值上,就会弹出一个菜单,选择“Symbolic constant”。 IDA就会自动列举枚举值,用以匹配当前的数值。

操作完成,我们就会得到下面的结果:

TOP

----------------------------------------------------------------------------------------------------- 第七节:Bit-fields(位域)

BTW:Bit-fields,我的理解就是在结构体中的位标志。太菜!希望高手指正!

现在,我们来定义一下在software_info_t 结构中的bitfields。 IDA的观点就是,bitefields是一种特殊的枚举类型。 我们可以选择在枚举类型创造窗口中的“Bitfield”选项。

还记得我们曾经在我们的程序中建立了两种不同类型的bitfields ,

plateform和os包含了一种隐藏的模式:用来包含组合模式(用逻辑或来操作) 。因为一种产品可以同时在几种plateforms和OS的组合。另一方面,category bitfield 中每一个数字表示一种类别:一种产品每次只能属于一种类别。

在IDA中一种指定的模式,bitfield只能包含一个值。所以在描述plateform 和category bitfields时为了显示组合模式,我们必须创建一个小的bitfields,每个值的一个bit.

现在我们开始创建category bitfield。mask值为0x3 (2 bits).我们指定一个名字、一个值、还有bitfield mask。我们还需要定义mask的名字:这个我们不用IDA自动生成的,IDA有一个内存助手可以帮助生成。

当所有的bitfields被输入,我们就会得到下面的结果:

用Operands 工具栏上的Enum member命令就可以定义我们程序中的Enum member数据

TOP

--------------------------------------------------------------------------------------------------------- 第八节:结构体

我们的程序当中包含了很多结构体。现在让我们来在IDA中描述一下结构体, 看看是怎么提高汇编代码的可读性。

第一步,我们必须打开Structures 窗口,来创建一个新的结构体类型。

结构体的成员是一汇编的模式定义的。让我们来定义software_t 结构中的第一个成员。 一直按“D”知道它变成“dd”意思就是这个成员的值为 dword类型。

把它的格式定义为我们以前定义好的software_info_t 枚举类型,然后我们用Rename命令输入一个适当的名字:info

开始定义第二个成员,这次使用ASCII命令(按“A”),在这个环节 IDA会弹出一个专用对话框用来设定字符串的大小

我们还可以从已经分析好的数据中来建立结构体。

举个例子:假设我们选择了一块数据正好是和我们的customer_t结构体的数据格式一样,我们就可以用IDA的“Create struct from data ”命令来创建结构体

一旦使用了这个命令,IDA就会在Structures窗口创建一个相对应的结构体

我们使用“A”键来修改name成员的长度为32bytes(和我们源代码中定义的一样),然后再给结构体一个好听的名字。

我们拿这些结构体有什么用呢?IDA提供给我们两种方法: ·Apply structure types to initialized data in the program. ·Convert operands as offsets inside structures. 我们将在下面的教程当中来介绍这两种方法

TOP

--------------------------------------------------------------------------------------------------------------------- 第九节:结构变量和结构数组

现在让我们用来customer_t结构体整理另外一个客户信息John。

把鼠标指针放在我们定义的结构体的第一个自己上面,然后使用Struct var命令。

这样我们就得到了一个新的结构体变量。IDA会自动在结构体成员的后面加上变量名的。

通过我们的源码,我们知道有一个包含个4元素的customers数组,我们先前把

Peter和John都定义为 customer_t 结构体了。现在取消对Join结构变量的定义,然后在Peter结构上按“*”键创建我们的customer数组,这样IDA就弹出一个数组设置框他会自动检测出来我们要创建的数组最大数是4。

下来我们就看到创建好的数组了,剩下的就是改一下数组的名字。

TOP

------------------------------------------------------------------------------------------------------- 第十节:联合体和结构体中的结构体

IDA中可以像定义标准结构体那样来定义联合体。 让我们来试着定义product_u 这个联合体吧。 book_t和software_t这两个结构体我们已经定义过了。

IDA认为联合体就是一种特别的结构体:因此我们打开Structures窗口,运行Add struct type命令,在对话框中我们选择创建Create union 选项。

我们可以使用IDA常用的命令来创建联合体成员,分别添加一个book_t 结构体类型的book和一个software_t 结构体的software联合体成员

当然结构体也可以嵌套一个结构体。事实上,我们刚才做的例子就实现了。 记住IDA认为联合体只不过是一种特殊的结构体

TOP

---------------------------------------------------------------------------------------------- 第十一节:可变的结构体

我们还记得有一个softwares_t 结构体。结构体softs 的长度是不确定的。

在汇编中,我们必须创建一个大小可变的结构体~。这种结构体创建的时候和普通的一样,仅仅最后一个元素定义的数组元素个数为0。

既然IDA不能计算出这种结构体的大小,我们就必须通过选择结构体的区域,来定义大小。

我们可以看到所有的类型IDA用注释模式来显示成员名称

TOP

---------------------------------------------------------------------------------------------------- 第十二节:结构体偏移

现在我们知道如何定义联合体和结构体了。现在我们来将一些操作数指向他们原本指向的结构体。

在print_customer() 函数中,我们知道他只有一个指向customer_t结构体的参数。EAX寄存器初始化这个指针的值,使他指向customer_t 结构体。因此我们推断所有的[EAX+....]都是指向customer_t结构体成员的偏移。

我们开始重新定义这些结构体变量的偏移,你右击在他们上面IDA会自动给你提供偏移的信息。

当我们把所有的偏移量都整理一下的话,汇编代码马上就变得清晰易懂了。

print_software()函数呢就是另外一个例子:EBX在初始化的时候指向了software_t 及构体。注意EBX寄存器在整个函数中都有应用(一个一个替换会累死的)。不要紧张,IDA会使用一次操作就能替换全部。 做法如下:

选择整个函数的代码,然后选在Operands工具栏上的Offset (struct) 命令。

弹出Structure offsets窗口。然我们在列表中选择EBX寄存器。 左边树形视图显示了在IDA中定义的所有结构。

右边就显示与EBX有关系的所有操作。如果我们选择了左边的一个结构,

IDA就会自动改变被选择代码中与结构体有关的偏移量。

树视图前面不同的符号表示经过计算后的状态。对号就表示完全匹配,相反就是不完全匹配。在我们的操作中正好完全匹配。

确定以后,我们就得到了下面的结果:

TOP

-------------------------------------------------------------------------------------------------------------- 第十三节:联合体偏移量

依靠产品种类,我们可以调用适当的函数来打印产品信息。

但是这一次的结构体偏移量跟以前不一样了,它是product_u联合体中的一个成员,它是一个数,这时我们就选择Edit struct 菜单中Select union member命令来处理

结果就是这样:

Structure offset对话框显示如何表明一个联合体成员。在你选择的区域中打开了这个窗口,IDA就会用“?”来显示联合体类型。

如果展开树视图中适当的分支,我们可以选择被描述为联合体成员的偏移量。 一旦选中,IDA会用在一种绿色的符号来表示偏移量指向的记录中的联合体。

TOP

-------------------------------------------------------------------------------------------------------- 第十四节:地址偏移量

IDA也可以重新定义操作数。在下面的例子中,桔黄色的部分显示一个可能存在的参考~

使用Operands 工具栏上的Offset 按钮就可以进行转换。

TOP

--------------------------------------------------------------------------------------------------------------------

第十五节:最终逆向结果

To end this tutorial, we propose you a visual comparison of the original C source code and our final interactively disassembled code. 来look look我们用IDA整理的结果把

struct customer_t { long id;

char name[32]; char sex; }

struct softwares_t { long count; software_t softs[]; }; struct book_t { char title[128]; }; struct software_t { software_info_t info; char name[32]; }; union product_u { book_t book; software_t software; }; struct product_t { long id; product_category_t category; product_u ; ------------------------------------------------------------- customer_t struc ; (sizeof=0x28) id dd ?

name db 32 dup(?) ; string(C) sex dd ? ; char customer_t ends

; ------------------------------------------------------------- softwares_t struc ; (sizeof=0x4, variable size) count dd ?

softs software_t 0 dup(?) softwares_t ends ; ------------------------------------------------------------- book_t struc ; (sizeof=0x80) title db 128 dup(?) ; string(C) book_t ends ; ------------------------------------------------------------- software_t struc ; (sizeof=0x24) info dd ? ; enum software_info_t name db 32 dup(?) ; string(C) software_t ends ; ------------------------------------------------------------- product_u union ; (sizeof=0x80) book book_t ? software software_t ? product_u ends ; ------------------------------------------------------------- product_t struc ; (sizeof=0x88) id dd ?

category dd ? ; enum product_category_t p product_u ? product_t ends

p; }; enum product_category_t { BOOK, SOFTWARE, HARDWARE }; struct software_info_t { unsigned int plateform : 2; #define PC 0x1 // 0x01 #define MAC 0x2 // 0x02 unsigned int os : 3; #define WINDOWS 0x1 // 0x04 #define DOS 0x2 // 0x08 #define OS_X 0x4 // 0x10 unsigned int category : 2; #define

DISASSEMBLY 0x1 // 0x20

#define RECOVERY 0x2 // 0x40 #define

CRYPTOGRAPHY 0x3 // 0x60 }; ; ------------------------------------------------------------- ; enum product_category_t BOOK = 0 SOFTWARE = 1 HARDWARE = 2 ; ------------------------------------------------------------- ; enum software_info_t (bitfield) PC = 1 MAC = 2 WINDOWS = 4 DOS = 8 OS_X = 10h

category = 60h DISASSEMBL Y = 20h RECOVERY = 40h CRYPTOGRAPHY = 60h ; +------------------------------------------------------------+

; |This file is generated by The Interactive Disassembler (IDA)| ; |Copyright (c) 2003 by DataRescue sa/nv, | ; | Licensed to: Eric |; +------------------------------------------------------------+

;

int

check_software(software_info_t

software_info) {

; File Name : C:\\IDA\\Presentations\\Data\\data.exe ; Format : Portable executable for IBM PC (PE) ; Section 1. (virtual address 00001000)

; Virtual size : 00009000 ( 36864.) ; Section size in file : 00008E00 ( 36352.) ; Offset to raw data for section: 00000600 ; Flags 60000020: Text Executable Readable ; Alignment : 16 bytes ?

unicode macro page,string,zero irpc c, db '&c', page endm

ifnb dw zero endif endm

model flat

; --------------------------------------------------------------

; Segment type: Pure code

; Segment permissions: Read/Execute _text segment para public 'CODE' use32 assume cs:_text ;org 401000h

; [COLLAPSED AREA .text1. PRESS KEYPAD \ ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||

; Attributes: bp-based frame

; int __cdecl check_software(software_info_t software_info) check_software proc near ; CODE XREF: main+108p

software_info= byte ptr 8 push ebp

mov ebp, esp mov al, 1

mov dl, [ebp+software_info]

bool valid = true; if

(software_info.plateform & PC) {

and edx, PC or MAC test dl, PC

jz shortnot_PC

mov cl, [ebp+software_info] and ecx, PC or MAC test cl, MAC jnz shortend

mov dl, [ebp+software_info] shr edx, 2

if (! (software_info.plateform

& MAC)

&&

(software_info.os & OS_X))

valid = false; }

else if (software_info.plateform

& MAC) {

if (! (software_info.plateform

& PC)

&& and edx, (WINDOWS or DOS or OS_X) >> 2 test dl, OS_X >> 2 jz shortend xor eax, eax jmp shortend

; --------------------------------------------------------------

not_PC: ; CODE XREF: check_software+Ej mov cl, [ebp+software_info] and ecx, PC or MAC test cl, MAC

jz shortnot_MAC

mov dl, [ebp+software_info] and edx, PC or MAC test dl, PC jnz shortend

mov cl, [ebp+software_info] shr ecx, 2

and ecx, (WINDOWS or DOS or OS_X) >> 2 test cl, WINDOWS >> 2 jnz shortnot_windows

mov dl, [ebp+software_info] shr edx, 2

and edx, (WINDOWS or DOS or OS_X) >> 2 test dl, DOS >> 2 jz shortend

not_windows: ; CODE XREF: check_software+4Fj xor eax, eax jmp shortend

; --------------------------------------------------------------

not_MAC: ; CODE XREF: check_software+36j xor eax, eax

((software_info.os end: ; CODE XREF: check_software+19j ... & xor edx, edx WINDOWS) mov dl, al mov eax, edx pop ebp retn || check_software endp (software_info.os & DOS))) ; -------------------------------------------------------------- valid = false; }

else

valid = false;

return valid; } int check_product(product_category_t product_category) { bool valid = true; align 4 ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||| ; Attributes: bp-based frame ; int __cdecl check_product(product_category_t product_category) check_product proc near ; CODE XREF: print_product+Ap main+D8p product_category= dword ptr 8 push ebp mov ebp, esp push ebx mov bl, 1 cmp [ebp+product_category], HARDWARE jnz shortnot_hardware

if

(product_category == HARDWARE) {

valid = false; printf(\don't sell hardware

for the xor ebx, ebx

push offset aWeDonTSellHardwareForThe ; format call _printf pop ecx

not_hardware: ; CODE XREF: check_product+Aj xor eax, eax mov al, bl moment...\\n\ }

return valid; } void

print_customer(customer_t *customer) {

printf(\X: %s (%c)\\n\ customer->id, customer->name, customer->sex);

pop ebx pop ebp retn

check_product endp

; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||

; Attributes: bp-based frame

; void __cdecl print_customer(customer_t *customer) print_customer proc near ; CODE XREF: main+19p

customer= dword ptr 8

push ebp

mov ebp, esp

mov eax, [ebp+customer]

movsx edx, byte ptr [eax+customer_t.sex] push edx

lea ecx, [eax+customer_t.name] push ecx

push [eax+customer_t.id]

push offset aCustomer04xSC ; format call _printf add esp, 10h pop ebp retn

print_customer endp

} void

print_book(book_t *book) {

printf(\book->title); } void

print_software(software_t

*software) {

; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||

; Attributes: bp-based frame

; void __cdecl print_book(book_t *book)

print_book proc near ; CODE XREF: print_product+38p

book= dword ptr 8

push ebp

mov ebp, esp push [ebp+book]

push offset aBookS ; format call _printf add esp, 8 pop ebp retn

print_book endp

; ------------------------------------------------------------- align 4

; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||

; Attributes: bp-based frame

; void __cdecl print_software(software_t *software)

print_software proc near ; CODE XREF: print_product+44p

software= dword ptr 8

push ebp

mov ebp, esp push ebx push esi

mov ebx, [ebp+software]

mov esi, offset aWeDonTSellHardwareForThe lea eax, [ebx+software_t.name]

printf(\%s:\

software->name); if

(software->info.plateform & PC)

printf(\ if

(software->info.plateform & MAC)

printf(\

printf(\ if

(software->info.os & WINDOWS) push eax

lea edx, (aSoftwareS - aWeDonTSellHardwareForThe)[esi] push edx ; format call _printf add esp, 8

mov cl, byte ptr [ebx+software_t.info] and ecx, PC or MAC test cl, PC

jz shortnot_pc

lea eax, (aPc - aWeDonTSellHardwareForThe)[esi] push eax ; format call _printf pop ecx

not_pc:

mov dl, byte ptr [ebx+software_t.info] and edx, PC or MAC test dl, MAC

jz shortnot_mac

lea ecx, (aMac - aWeDonTSellHardwareForThe)[esi] push ecx ; format call _printf pop ecx

not_mac:

lea eax, (asc_40A31B - aWeDonTSellHardwareForThe)[esi] push eax ; format call _printf pop ecx

mov dl, byte ptr [ebx+software_t.info] shr edx, 2

and edx, (WINDOWS or DOS or OS_X) >> 2 test dl, WINDOWS >> 2 jz shortnot_windows

lea ecx, (aWindows - aWeDonTSellHardwareForThe)[esi] push ecx ; format call _printf pop ecx

not_windows:

mov al, byte ptr [ebx+software_t.info] shr eax, 2

and eax, (WINDOWS or DOS or OS_X) >> 2 test al, DOS >> 2

printf(\WINDOWS\ if

(software->info.os & DOS)

printf(\ if

(software->info.os & OS_X)

printf(\

printf(\

switch(software->info.category) { jz shortnot_dos

lea edx, (aDos - aWeDonTSellHardwareForThe)[esi] push edx ; format call _printf pop ecx

not_dos:

mov cl, byte ptr [ebx+software_t.info] shr ecx, 2

and ecx, (WINDOWS or DOS or OS_X) >> 2 test cl, OS_X >> 2 jz shortnot_os_x

lea eax, (aOsX - aWeDonTSellHardwareForThe)[esi] push eax ; format call _printf pop ecx

not_os_x:

lea edx, (asc_40A331 - aWeDonTSellHardwareForThe)[esi] push edx ; format call _printf pop ecx

mov cl, byte ptr [ebx+software_t.info] shr ecx, 5

and ecx, category >> 5 dec ecx

jz shortDISASSEMBLY dec ecx

jz shortRECOVERY dec ecx

jz shortCRYPTOGRAPHY jmp shortend

; ------------------------------------------------------------

DISASSEMBLY:

lea eax, (aDisassembly - aWeDonTSellHardwareForThe)[esi] push eax ; format call _printf pop ecx

jmp shortend

; ------------------------------------------------------------

RECOVERY:

lea edx, (aRecovery - aWeDonTSellHardwareForThe)[esi]

push edx ; format

case

DISASSEMBLY:

printf(\DISASSEMBLY\

break;

case RECOVERY:

printf(\RECOVERY\

break;

case

CRYPTOGRAPHY:

printf(\

CRYPTOGRAPHY\ break; }

printf(\

call _printf pop ecx

jmp shortend

; ------------------------------------------------------------

CRYPTOGRAPHY:

lea ecx, (aCryptography - aWeDonTSellHardwareForThe)[esi] push ecx ; format call _printf pop ecx end:

lea eax, (asc_40A358 - aWeDonTSellHardwareForThe)[esi] push eax ; format call _printf pop ecx pop esi pop ebx pop ebp retn

print_software endp

; ------------------------------------------------------------ align 4

} bool

print_product(product_t *product) {

if (! check_product(

product->category))

return false;

printf(\X: \

product->id);

switch(product->category) {

; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||

; Attributes: bp-based frame

; int __cdecl print_product(product_t *product) print_product proc near ; CODE XREF: main+128p

product= dword ptr 8

push ebp

mov ebp, esp push ebx

mov ebx, [ebp+product]

push [ebx+product_t.category] ; product_category call check_product pop ecx test eax, eax

jnz shortcheck_product_ok xor eax, eax pop ebx pop ebp retn

; ------------------------------------------------------------

check_product_ok: ; CODE XREF: print_product+12j push [ebx+product_t.id]

push offset aProduct04x ; format call _printf add esp, 8

mov edx, [ebx+product_t.category] sub edx, 1

jb shortcase_book jz shortcase_software jmp shortdefault

; ------------------------------------------------------------

case_book: ; CODE XREF: print_product+2Ej add ebx, product_t.p.book.title push ebx ; book

case BOOK:

print_book(&product->p.book);

break;

case SOFTWARE:

print_software(

&product->p.software);

break; }

return true; }

void main() {

call print_book pop ecx

jmp shortdefault

; ------------------------------------------------------------

case_software: ; CODE XREF: print_product+30j add ebx, product_t.p.software.info push ebx ; software call print_software pop ecx

default: ; CODE XREF: print_product+32j ... mov al, 1 pop ebx pop ebp retn

print_product endp

; ------------------------------------------------------------ align 4

; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||

; Attributes: bp-based frame

; void __cdecl main()

main proc near ; DATA XREF: .data:0040A0D0o push ebp

mov ebp, esp push ebx push esi push edi

push offset aCustomers ; format call _printf printf(\ pop ecx :\\n\ mov ebx, offset customers jmp short loc_401376 customer_t ; ------------------------------------------------------------ *customer = customers; while (customer->id != 0) { print_customer(customer); customer++; } product_t *products = (product_t*) malloc(PRODUCTS_COUNT * sizeof(product_t)); products[0].id = 1; products[0].category = BOOK; products[0].p.book = ida_book; products[1].id = 2; loop_print_customer: ; CODE XREF: main+25j push ebx ; customer call print_customer pop ecx add ebx, 40 loc_401376: ; CODE XREF: main+16j cmp [ebx+customer_t.id], 0 jnz shortloop_print_customer push 544 ; size call _malloc pop ecx mov ebx, eax mov [ebx+product_t.id], 1 xor eax, eax ; BOOK mov [ebx+product_t.category], eax

mov esi, offset aIdaQuickstartG ; \ lea edi, [ebx+product_t.p.book.title] mov ecx, 32 rep movsd mov dword ptr [ebx+product_t[1].id], 2 mov dword ptr [ebx+product_t[1].category], SOFTWARE mov esi, offset softwares.softs lea edi, [ebx+product_t[1].p.software] mov ecx, 9 rep movsd mov dword ptr [ebx+product_t[2].id], 3

mov dword ptr [ebx+product_t[2].category], SOFTWARE mov esi, (offset softwares.softs.info+24h) lea edi, [ebx+product_t[2].p.software] mov ecx, 9 rep movsd mov dword ptr [ebx+product_t[3].id], 4 mov dword ptr [ebx+product_t[3].category], SOFTWARE mov esi, (offset softwares.softs.info+48h) lea edi, [ebx+product_t[3].p.software] mov ecx, 9

rep movsd

products[1].category push offset aProducts ; format = SOFTWARE; call _printf pop ecx products[1].p.softwar xor esi, esi e =

softwares.softs[0]; loop_verify_print_product: ; CODE XREF: main+132j products[2].id = 3; products[2].category = SOFTWARE; products[2].p.software = softwares.softs[1]; products[3].id = 4; products[3].category = SOFTWARE; products[3].p.software = softwares.softs[2]; printf(\:\\n\ for (int i = 0; i < PRODUCTS_COUNT; i++) { mov eax, esi shl eax, 4 add eax, esi push [ebx+eax*8+product_t.category] ; product_category call check_product pop ecx test eax, eax jnz shortproduct_is_valid

push offset aInvalidProduct ; format call _printf pop ecx jmp shortexit ; ------------------------------------------------------------ product_is_valid: ; CODE XREF: main+E0j mov edx, esi shl edx, 4 add edx, esi cmp [ebx+edx*8+product_t.category], SOFTWARE jnz shortprint_product mov ecx, esi shl ecx, 4 add ecx, esi push [ebx+ecx*8+product_t.p.software.info] ; software_info call check_software pop ecx test eax, eax jnz shortprint_product push offset aInvalidSoftwar ; format call _printf pop ecx jmp shortexit ; ----------------------------------------------------------- print_product: ; CODE XREF: main+FBj main+110j imul eax, esi, 88h add eax, ebx

if (! check_product(

products[i].category)) push eax ; product call print_product pop ecx inc esi cmp esi, 4

{

printf(\product !!!\\n\

break; }

if

(products[i].category == SOFTWARE) {

if (! check_software(

products[i].p.software.info)) {

printf(\ software !!!\\n\

break; } }

jl shortloop_verify_print_product

exit: ; CODE XREF: main+EDj main+11Dj push ebx ; block call _free pop ecx pop edi pop esi pop ebx pop ebp retn main endp

print_product(&products[i]); }

free(products); }

customer_t customers[] = { { 1,

\ 'm' },

; [COLLAPSED AREA .text2. PRESS KEYPAD \; [COLLAPSED AREA .text2. PRESS KEYPAD \; Section 2. (virtual address 0000A000)

; Virtual size : 00003000 ( 12288.) ; Section size in file : 00002800 ( 10240.) ; Offset to raw data for section: 00009400 ; Flags C0000040: Data Readable Writable ; Alignment : 16 bytes ?

; ------------------------------------------------------------

; Segment type: Pure data

; Segment permissions: Read/Write

_data segment para public 'DATA' use32 assume cs:_data ;org 40A000h

; [COLLAPSED AREA .data1. PRESS KEYPAD \

customers dd 1 ; id ; DATA XREF: main+11o db 'Peter',0,0,0,0,0,0,0,0,0,0,0,0,0,0,... ; name dd 'm' ; sex dd 2 ; id

{ 2, \ 'm' }, { 3, \ 'f' }, { 0 } }; book_t ida_book = { \ Guide\

softwares_t softwares = { 3, { { { PC, WINDOWS|DOS, DISASSEMBLY }, \ { { PC|MAC, WINDOWS|OS_X, RECOVERY },

\ { { PC, WINDOWS,

CRYPTOGRAPHY }, \ } }; db 'John',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... ; name dd 'm' ; sex dd 3 ; id db 'Mary',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... ; name dd 'f' ; sex dd 0 ; id db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,... ; name db 0 ; name dd 0 ; sex

aIdaQuickstartG db 'IDA QuickStart Guide',0 ; DATA XREF:... db 6Bh dup(0) softwares dd 3 ; count ; DATA XREF: main+62o dd PC or WINDOWS or DOS or DISASSEMBLY; softs.info

db 'IDA Pro',0,0,0,0,0,0,0,0,0,0,0,0,0,...; softs.name dd PC or MAC or WINDOWS or OS_X or RECOVERY; softs.info db 'PhotoRescue',0,0,0,0,0,0,0,0,0,0,0,...; softs.name dd PC or WINDOWS or CRYPTOGRAPHY; softs.info db 'aCrypt',0,0,0,0,0,0,0,0,0,0,0,0,0,0,...; softs.name aWeDonTSellHardwareForThe db 'We don',27h,'t sell

hardware... ; DATA XREF: check_product+Eo... aCustomer04xSC db 'CUSTOMER X: %s (%c)',0Ah,0 ;... aBookSdb 'BOOK: %s',0Ah,0 ; DATA XREF: print_book+6o

aSoftwareS db 'SOFTWARE: %s:',0 ; DATA XREF:...aPc db ' PC',0 ; DATA XREF: print_software+27r

aMac db ' MAC',0 ; DATA XREF: print_software+3Br asc_40A31B db ';',0 ; DATA XREF: print_software+45r

aWindows db ' WINDOWS',0 ; DATA XREF:...aDos db ' DOS',0 ; DATA XREF: print_software+72r

aOsX db ' OS-X',0 ; DATA XREF: print_software+89r asc_40A331 db ';',0 ; DATA XREF: print_software+93r aDisassembly db ' DISASSEMBLY',0 ; DATA XREF:...

aRecovery db ' RECOVERY',0 ; DATA XREF:...aCryptography db ' CRYPTOGRAPHY',0 ; DATA XREF:...asc_40A358 db 0Ah,0 ; DATA XREF: print_software+D8r

aProduct04x db 'PRODUCT X: ',0 ; DATA XREF:...aCustomers db 'CUSTOMERS:',0Ah,0 ; DATA XREF:...aProducts db 0Ah ; DATA XREF: main+C0o

db 'PRODUCTS:',0Ah,0

aInvalidProduct db 'Invalid product !!!',0Ah,0 ;...aInvalidSoftwar db 'Invalid software !!!',0Ah,0 ;...

TOP 附录

#include

// our structures

// ==============

// information about our customers struct customer_t {// a typical structure long id;

char name[32];

char sex;// 'm'ale - 'f'emale };

// we sell books struct book_t {

char title[128];// an ASCII string };

// and we sell computer softwares

struct software_info_t {// a structure containing various bitfields

unsigned int plateform : 2;// 2 bits reserved for the plateform - plateforms can be combined (0x03) #definePC 0x1// 0x01 #defineMAC 0x2// 0x02

unsigned int os : 3;// 3 bits reserved for the OS - OS can be combined (0x1C) #defineWINDOWS 0x1// 0x04

#defineDOS 0x2// 0x08 #defineOS_X 0x4// 0x10

unsigned int category : 2;// 2 bits reserved for the category - categories can't be combined (0x60) #defineDISASSEMBLY 0x1// 0x20 #defineRECOVERY 0x2// 0x40 #defineCRYPTOGRAPHY 0x3// 0x60 };

struct software_t { software_info_t info; char name[32]; };

struct softwares_t {// a variable length structure to memorize our softwares long count; software_t softs[]; };

// generic products we're selling

enum product_category_t {// an enumerated type BOOK, SOFTWARE,

HARDWARE// we actually don't sell hardware };

union product_u {// an union to contain product information depending on its category book_t book; software_t software;

// struct hardware_t hardware; // we actually don't sell hardware };

struct product_t {// a structure containing another structure long id;

product_category_t category; product_u p; }; // our data // ======== // our customers

customer_t customers[] = {// an initialized array to memorize our customers { 1, \ { 2, \ { 3, \ { 0 } };

// our products

book_t ida_book = { \

softwares_t softwares =// an initialized variable length structure

{ 3, {

{ { PC, WINDOWS|DOS, DISASSEMBLY }, \ { { PC|MAC, WINDOWS|OS_X, RECOVERY }, \ { { PC, WINDOWS, CRYPTOGRAPHY }, \ } };

#definePRODUCTS_COUNT 4

// our functions // ============= // check software information

int check_software(software_info_t software_info) {

bool valid = true;

if (software_info.plateform & PC) {

if (! (software_info.plateform & MAC) && (software_info.os & OS_X)) valid = false;// OS-X isn't yet available on PC ;) }

else if (software_info.plateform & MAC) {

if (! (software_info.plateform & PC) && ((software_info.os & WINDOWS) || (software_info.os & DOS)))

valid = false;// Windows & DOS aren't available on Mac... } else valid = false; return valid; }

// check product category

int check_product(product_category_t product_category) {

bool valid = true;

if (product_category == HARDWARE) {

valid = false;

printf(\ }

return valid; }

// print customer information

void print_customer(customer_t *customer) {

printf(\customer->id, customer->name, customer->sex); }

// print book information void print_book(book_t *book) {

printf(\book->title); }

// print software information

void print_software(software_t *software) {

printf(\software->name); // plateform

// we use 'if', as plateforms can be combined if (software->info.plateform & PC) printf(\

if (software->info.plateform & MAC) printf(\ printf(\ // OS

// we use 'if', as os can be combined if (software->info.os & WINDOWS) printf(\ if (software->info.os & DOS) printf(\

if (software->info.os & OS_X) printf(\ printf(\ // category

// we use 'switch', as categories can't be combined switch(software->info.category) {

case DISASSEMBLY: printf(\ break;

case RECOVERY: printf(\ break;

case CRYPTOGRAPHY: printf(\

break; }

printf(\ }

// print product information

bool print_product(product_t *product) {

if (! check_product(product->category)) return false;

printf(\product->id); switch(product->category) { case BOOK:

print_book(&product->p.book); break;

case SOFTWARE:

print_software(&product->p.software); break; } return true; }

// our main program // ================ void main() {

// print customers listing printf(\ customer_t *customer = customers; while (customer->id != 0) {

print_customer(customer); customer++; }

// allocate a small array to store our products in memory

product_t *products = (product_t*) malloc(PRODUCTS_COUNT * sizeof(product_t)); // insert our products products[0].id = 1;

products[0].category = BOOK; products[0].p.book = ida_book; products[1].id = 2;

products[1].category = SOFTWARE;

products[1].p.software = softwares.softs[0];// we insert softwares from our variable length structure products[2].id = 3;

products[2].category = SOFTWARE;

products[2].p.software = softwares.softs[1]; products[3].id = 4;

products[3].category = SOFTWARE; products[3].p.software = softwares.softs[2]; // verify and print each product printf(\

for (int i = 0; i < PRODUCTS_COUNT; i++) {

// check validity of the product category if (! check_product(products[i].category)) {

printf(\ break; }

// check validity of softwares

if (products[i].category == SOFTWARE) {

if (! check_software(products[i].p.software.info)) {

printf(\ break; } }

// and print the product print_product(&products[i]); }

free(products); }

本文来源:https://www.bwwdw.com/article/te4r.html

Top