编程语言
首页 > 编程语言> > 《C++反汇编与逆向分析技术揭秘》--钱林松,赵海旭 著

《C++反汇编与逆向分析技术揭秘》--钱林松,赵海旭 著

作者:互联网

1 熟悉工作环境和相关工具

1.1 调试工具Microsoft Visual C++6.0和OllyDBG

1.2 反汇编静态分析工具IDA

1.3 反汇编引擎的工作原理


2 基本数据类型的表现形式

2.1 整数类型

2.2 浮点数类型

2.3 字符和字符串

2.4 布尔类型

2.5 地址、指针和引用

2.6 常量


3 认识启动函数,找到用户入口

3.1 程序的真正入口

3.2 了解VC++6.0的启动函数

3.3 main函数的识别


4 观察各种表达式的求值过程

4.1 算术运算和赋值

4.2 关系运算和逻辑运算

4.3 位运算

4.4 编译器使用的优化技巧

4.5 一次算法逆向之旅


5 流程控制语句的识别

5.1 if语句

#include<stdio.h>
int main()
{
	int a=2;
	if (a==2)//注意与汇编位置对比
	{
		printf("%d",a);
	}
	return 0;
}

image-20211003092942039

image-20211003093502615

5.2 if...else...语句

#include<stdio.h>
int main()
{
	int a=2;
	if (a==2)
	{
		printf("a等于2");
	}
	else{
		printf("a不等于2");
	}
	return 0;
}

image-20211003094550882

总结:
;先执行影响标志位的指令
jcc ELSE_BEGIN  ;重点
IF_BEGIN:
...
IF_END:
jmp ELSE_END    ;重点
ELSE_BEGIN:
...
ELSE_END:

5.3 用if构成的多分支流程

#include<stdio.h>
int main()
{
	int a=2;
	if (a<0)
	{
		printf("a小于2");
	}
	else if(a==2)
	{
		printf("a等于2");
	}
	else
	{
		printf("a为其他");
	}
	return 0;
}

image-20211003101243644

image-20211003101433819

总结:
;会影响标志位的指令 
JCC ELSE_IF_BEGIN   //if条件不成立,跳转到下一条if_else首地址
IF_BEGIN:
...            //if条件成立执行代码块
IF_END: 
jmp END      //执行if后跳出到结束地址

ELSE_IF_BEGIN:      //else_if条件不成立,跳转到else首地址
;会影响标志位的指令
JCC ELSE_BEGIN
...             //else_if条件成立,执行代码块
ELSE_IF_END:
jmp END    //执行else_if后跳出到结束地址

ELSE_BEGIN:   //if和else_if条件都不成立,执行else代码
...
ELSE_END   //执行完就结束了,不用再跳转了
...
END:
...

5.4 switch的真相

#include<stdio.h>
int main()
{
	int nIndex = 1;
	scanf_s("%d", &nIndex);
	switch (nIndex)
	{
	case 1:
		printf("nIndex==1");
	case 2:
		printf("nIndex==2");
	case 100:
		printf("nIndex==100");
	}
	return 0;
}

image-20211003105522799

image-20211003105622944

int main()
{
000C18B0  push        ebp  
000C18B1  mov         ebp,esp  
000C18B3  sub         esp,0D4h  
000C18B9  push        ebx  
000C18BA  push        esi  
000C18BB  push        edi  
000C18BC  lea         edi,[ebp-14h]  
000C18BF  mov         ecx,5  
000C18C4  mov         eax,0CCCCCCCCh  
000C18C9  rep stos    dword ptr es:[edi]  
000C18CB  mov         eax,dword ptr [__security_cookie (0CA024h)]  
000C18D0  xor         eax,ebp  
000C18D2  mov         dword ptr [ebp-4],eax  
000C18D5  mov         ecx,offset _A43DB3BE_源@cpp (0CC003h)  
000C18DA  call        @__CheckForDebuggerJustMyCode@4 (0C1316h)  

	int nIndex = 1;
000C18DF  mov         dword ptr [nIndex],1  
	scanf_s("%d", &nIndex);
000C18E6  lea         eax,[nIndex]  
000C18E9  push        eax  
000C18EA  push        offset string "%s" (0C7B30h)  
000C18EF  call        _scanf_s (0C13C0h)  
000C18F4  add         esp,8  
	switch (nIndex)
000C18F7  mov         eax,dword ptr [nIndex]  
000C18FA  mov         dword ptr [ebp-0D4h],eax  
000C1900  cmp         dword ptr [ebp-0D4h],1  
000C1907  je          __$EncStackInitStart+61h (0C191Dh)  
000C1909  cmp         dword ptr [ebp-0D4h],2  
000C1910  je          _printf+0Ah (0C192Ah)  
000C1912  cmp         dword ptr [ebp-0D4h],64h  
000C1919  je          _printf+17h (0C1937h)  
000C191B  jmp         _printf+24h (0C1944h)  
	{
	case 1:
		printf("nIndex==1");
000C191D  push        offset string "two" (0C7B34h)  
000C1922  call        _printf (0C10CDh)  
000C1927  add         esp,4  
	case 2:
		printf("nIndex==2");
000C192A  push        offset string "nIndex==2" (0C7BE4h)  
000C192F  call        _printf (0C10CDh)  
000C1934  add         esp,4  
	case 100:
		printf("nIndex==100");
000C1937  push        offset string "nIndex==100" (0C7BF0h)  
000C193C  call        _printf (0C10CDh)  
000C1941  add         esp,4  
	}
	return 0;
000C1944  xor         eax,eax  
}

5.5 难以构成跳转表的switch

5.6 降低判定树的高度

5.7 do/while/for的比较

5.8 编译器对循环结构的优化


6 函数的工作原理

6.1 栈帧的形参和关闭

6.2 各种调用方式的考察

6.3 使用ebp或esp寻址

6.4 函数的参数

6.5 函数的返回值

6.6 回顾


7 变量在内存中的位置和访问方式

7.1 全局变量和局部变量的区别

7.2 局部静态变量的工作方式

7.3 堆变量


8 数组和指针的寻址

8.1 数组在函数内

8.2 数组作为参数

8.3 数组作为返回值

8.4 下标寻址和指针寻址

8.5 多维数组

8.6 存放指针类型数据的数组

8.7 指向数组的指针变量

8.8 函数指针


9 结构体和类

9.1 对象的内存布局

9.2 this指针

9.3 静态数据成员

9.4 对象作为函数参数

9.5 对象作为返回值


10 关于构造函数和析构函数

10.1 构造函数的出现时机

10.2 每个对象都有默认的构造函数吗

10.3 析构函数的出现时机


11 关于虚函数

11.1 虚函数的机制

11.2 虚函数的识别


12 从内存角度看继承和多重继承

12.1 识别类和类之间的关系

12.2 多重继承

12.3 抽象类

12.4 菱形继承


13 异常处理

13.1 异常处理的相关知识

13.2 异常类型为基本数据类型的处理流程

13.3 异常类型为对象的处理流程

13.4 识别异常处理


14 PEiD的工作原理分析

14.1 开发环境的识别

14.2 开发环境的伪造


15 “熊猫烧香”病毒逆向分析

15.1 调试环境配置

15.2 病毒程序初步分析

15.3 “熊猫烧香”启动过程分析

15.4 “熊猫烧香”的自我保护分析

15.5 “熊猫烧香”的感染过程分析


16 调试器OllyDBG的工作原理分析

16.1 INT3断点

16.2内存断点

16.3 硬件断点

16.4 异常处理机制

16.5 加载调试程序


17 反汇编代码的重建与编译

17.1 重建反汇编代码

17.2 编译重建后的反汇编代码

标签:--,跳转,C++,else,钱林松,ebp,printf,ELSE,nIndex
来源: https://www.cnblogs.com/ruler3389/p/15363773.html