公开课·

公开课1月3号·

老师根据PE结构图直接在在十六进制中找入口点时还是没听懂/没跟上 | 工具:PEiE

初级班的项目

  • 反汇编引擎:使用主流软件会被检测到
  • PE分析器:外挂、破解、病毒基础
  • 游戏案例逆向分析/加密壳(二选一)

毕业课题:商业软件开发模板:登录、进程注入、网络验证、隐藏模块、代码加密

公开课1月4号·

逻辑运算:与或非异或、

实现加法:两数异或,两数与运算,左移以为若不全为0,则须异或结果与左移后结果再次异或,并相与,左移为0则结束

并且通过and来判断需要进位的运算是否完成了

寄存器位于CPU内部

介绍了各类32位通用寄存器

BYTE 8BIT字节 WORD 16BIT字 DWORD 32BIT双字

32位是由于数据宽度为32位 | 内存单元的宽度为8个十六进制,4X8bit==32位

64位XP的优点有以下几个: 1、支持4G以上大内存,64位系统的共性,

32位系统理论上只支持4G内存,但可以突破限制:

32 位 Windows 系统是否能够使用 4GB 及以上的内存? - 知乎 (zhihu.com)

教你让XP等32位操作系统支持4G以上大内存,并且不出错_32位xp 扩大内存-CSDN博客

练习内存的读写时,MOV 地址,地址可以选择ESP或某某寄存器相关位置,避免程序崩溃

寻址公式4:[reg+reg*{1,2,4,8}] 寄存器可乘1,2,4,8(乘数取值由于硬编码)

15年的QQ聊天窗口里都有广告😄,游戏送神装

push esp && pop 变形:用mov和lea替代

最后卡了,堆栈也没听懂

画出指令的堆栈图

公开课1月5号·

无法打开 源 文件“stdafx.h”的解决方法-CSDN博客 | 老师使用的是

1
2
3
4
5
6
7
8
9
10
11
#include "stdio.h"
int Plus(int x, int y)
{
int z = 2;
return x + y + z;
}
int main(int argc, char* argv[])
{
int r = Plus(3, 4);
return 0;
}

不过自己生成的exe不知道怎么找到老师的那个

x64dbg没有提供 find sequence of commands 功能,要想搜索多条指令,可以用特征码匹配来代替。

可以右键选择搜索–当前区域–匹配特征,把两条指令的字节码填入搜索即可。

x64dbg 搜索多条指令 ( find sequence of commands )_x64debug搜索功能-CSDN博客

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "stdafx.h"
void Attack()
{
while(1)
{
printf("攻击程序\n");
}
getchar();
}
int main(int argc,char* argv[])
{
int arr[5] = {0};
arr[6] = (int)Attack;
return 0;
}

/*text overflow*/
#include "stdafx.h"
void HelloWorld()
{
int i=0;
int a[]={1,2,3,4,5,6,7,8,9,10};
for(i=0;i<=10;i++)
{
a[i]=0;
printf("Hello World\n");
}
}
int main(int argc,char* argv[])
{
HelloWorld();
getchar();
return 0;
}

typedef 函数指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "stdafx.h"

int Plus(int x,int y){
return x+y;
}
typedef int (*pFunciton)(int x,int y);

int main(int argc,char* argv[])
{
int z=Plus(1,2);
printf("%d\n",z);
pFunction p =(pFunciton)Plus;
int m = p(4,5);
printf("%d\n",m);
getchar();
return 0;
}

antidebug类似shellcode

数组里放一堆十六进制数 ,函数 涉及到了加壳的思想

1
2
3
4
5
6
7
8
9
10
11
12
unsigned char loc[] =
{
0x55,
}
typedef int (*fun)(int x,int y);
int main()
{
fun f = (fun) &loc;
printf("%x",f(4,5));
getchar();
return 0;
}

计算机底层相关基础·

进制·

二进制从0写到30

0 1 10 11 100 101 110 111 1000 1001 1010

1011 1100 1101 1110 1111 10000 10001 10010 10011 10100

10101 10110 10111 11000 11001 11010 11011 11100 11101 11110

八进制0写到80

0 1 2 3 4 5 6 7

10 11 12 13 14 15 16 17

… 第一个数行数 第二个数0到7

70 71 72 73 74 75 76 77(64个数 8的平方)

100 101 102 103 104 105 106 107 😄 忘了100

110 111 112 113 114 115 116 117

记住二进制和十六进制的映射关系

八进制加法:4+5== 4+4进位 +1 ==11 或全转为十进制算完后转回八进制 或根据基数计算

或本质:创建加法、乘法表,查表计算即可

作业:构建7进制、16进制的加法乘法表,并计算

进制直接跳了

数据宽度_逻辑运算·

八进制2-5 === 1 777 777 777 777 777 777 775。为什么

使用异或堆 87AD6 加密后解密,密钥:5

按照单个字符转为二进制,异或运算加解密

只用逻辑运算计算2-3

-3 ==D 1101 负数补码为正数取反+1,正数是本身

负数-3 原码是1011 第一位符号位不参与变换 后面的取反+1

0010-0011 0010+ 1011错

0010 + 1101

1111 与0000 与运算结果为0结束

此时求得的是结果的补码 ,除符号位取反加1得到原码1001 即-1

彻底弄清补码加减法运算,正数、负数位移运算原理_正数的补码加负数的补码怎么算-CSDN博客


以下为错误的:

1001 0010

异或0001 或(同时为1则为1) 0010 0100

0100 - 0001

0101 或 0000

加法:异或 与 判断是否为0

正数第一位是0,负数第一位是1;数据超限,直接截断

要学得如痴如醉

最后带着通过OD 练习mov eax,0x1等等 | 通过MOV指令修改8个寄存器的值F8单步执行,并观察修改后的结果

通用寄存器_内存读写·

32位寄存器、16位、8位 EAX AX AH AL

演示了寄存器间的MOV操作

imm表示立即数

MOV 目标操作数,源操作数 可以是通用寄存器、段寄存器、内存单元、立即数(但不能同时为内存单元)数据宽度需一致

ADD操作 SUB操作 AND OR XOR NOT

达到知道执行后会是什么结果

内存编号就是 0xffffffff加上中括号,区分立即数

向内存中写入须指明数据宽度

mov eax,dword ptr ds:[0x0012FF34]

dword读写多少 ptr指针(地址) ds段寄存器 0x0012FF34内存编号 | 内存并非都能读写(内存保护) 建议写esp(堆栈)的值

为什么X86汇编中的mov指令不支持内存到内存的寻址? | https://stackoverflow.com/questions/11953352/why-ia32-does-not-allow-memory-to-memory-mov·

练习2:内存寻址方式

内存地址_堆栈·

小端序 40min

标志寄存器·

  • PE
  • 下断点
  • WIN32 API
  • 函数调用
  • 熟悉堆栈-画过堆栈图
  • Call JCC 标志寄存器

45min JZ函数下断点 zero寄存器修改为1


标志寄存器: CF标志位:进位 数据宽度的最高位 进位为1

PF:结果中1的个数为偶数,PF为1

AF:辅助进位寄存器

zero :仅判断运算后,mov操作不改变寄存器的值XOR eax,eax可用于清零

SF 符号:最高位/运算结果符号位

OF溢出:有符号数

JCC·

堆栈图·

宝马问题·