ex可以发现

image-20221219101050969

是否加壳以及壳的版本

关于upx壳,有1.几,2.几,3.几三个大版本,用upxshell中的各个版本能脱掉大部分未魔改的壳

743232780

我存这个数干啥来着

忘记了。。

第一部分

TEA加密算法

早期腾讯使用,现在腾讯大多使用XTEA

特征常熟:

0x9e3779b5

算了还是做题吧,这视频讲的有点乱

image-20230324193719302

image-20230324201826154

JNZ - 如果 ZF 标志不为零 (1)

CMP - 如果两个值相等,

cmp相当于减法指令只是不保存结果

如果(ax)=(bx),则(ax)-(bx)=0,所以:zf=1;

如果(ax)≠(bx),则(ax)-(bx)≠0,所以:zf=0;

如果(ax)<(bx),则(ax)-(bx)将产生借位,,所以:cf=1;

如果(ax)≥(bx),则(ax)-(bx)不必借位,所以:cf=0;

如果(ax)>(bx),则(ax)-(bx)既不必借位,结果又不为0,所以:cf=0并且zf=0;

如果(ax)≤(bx),则(ax)-(bx)既可能借位,结果可能为0,所以:cf=1或zf=1;

指令cmp ax,bx的逻辑含义是比较ax和bx中的值,如果执行后:

zf=1,说明(ax)=(bx)

zf=0,说明(ax)≠(bx)

cf=1,说明(ax)<(bx)

cf=0,说明(ax)≥(bx)

cf=0并且zf=0,说明(ax)>(bx)

cf=1或zf=0,说明(ax)≤(bx)

结果为零则ZF=1

所以,根据cmp指令执行后zf的值,就可以知道两个数据是否相等。

上面所讲的是用cmp进行有符号数比较时,相关标志位对比较结果的记录。如果用cmp来进行有符号数比较时,CPU用哪些标志位对比较结果进行记录。例如

1
cmp ah,bh

如果(ah)=(bh),则(ah)-(bh)=0, 所以:zf=1

如果(ah)≠(bh),则(ah)-(bh)≠0, 所以:zf=0;

所以,根据cmp指令执行后zf的值,就可以知道两个数据是否相等。

最后以cmp ah,bh为例,总结一下CPU执行cmp指令后,sf和of的值是如何来说明比较的结果的.

1)如果sf=1,而of=0

of=0, 说明没有溢出,逻辑上真正结果的正负=实际结果的正负;

因sf=1, 实际结果为负,所以逻辑上真正的结果为负,所以(ah)<(bh)。

2)如果sf=1,而of=1

of=1, 说明有溢出,逻辑上真正结果的正负≠实际结果的正负;

因sf=1, 实际结果为负。

实际结果为负,而又有溢出,这说明了是由于溢出导致了实际结果为负,简单分析一下,就可以看出,如果因为溢出导致了实际结果为负,那么逻辑上真正的结果必然为正。

这样,sf=1,of=1,说明了(ah)>(bh)。

3)如果sf=0, 而of=1

of=1, 说明有溢出,逻辑上真正结果的正负≠实际结果的正负;

因sf=0,实际结果非负。而of=1说明有溢出,则结果非0,所以实际结果为正。

实际结果为正,而又有溢出,这说明是由于溢出导致了实际结果非负,简单分析一下,就可以看出,如果因为溢出导致了实际结果为正,那么逻辑上真正的结果必然为负。

这样:sf=0, of=1,说明了(ah)<(bh)。

4)如果sf=0,而of=0

of=0, 说明没有溢出,逻辑上真正结果的正负=实际结果的正负;

因sf=0,实际结果非负,所以逻辑上真正的结果非负,所以(ah)≥(bh)。

若ZF=1(表示本次运算结果为0,不为0则ZF=0),则跳转,否则,不跳转ZF的状态根据其他指令的执行结果设置。

image-20230324201300256

如果小于八,就跳转指定的位置

x86 指令集包含大量的条件跳转指令。它们能比较有符号和无符号整数,并根据单个 CPU 标志位的值来执行操作。条件跳转指令可以分为四个类型:

  • 基于特定标志位的值跳转
  • 基于两数是否相等,或是否等于(E)CX 的值跳转
  • 基于无符号操作数的比较跳转
  • 基于有符号操作数的比较跳转

下表展示了基于零标志位、进位标志位、溢出标志位、奇偶标志位和符号标志位的跳转。

助记符 说明 标志位/寄存器 助记符 说明 标志位/寄存器
JZ 为零跳转 ZF=1 JNO 无溢出跳转 OF=0
JNZ 非零跳转 ZF=0 JS 有符号跳转 SF=1
JC 进位跳转 CF=1 JNS 无符号跳转 SF=0
JNC 无进位跳转 CF=0 JP 偶校验跳转 PF=1
JO 溢出跳转 OF=1 JNP 奇校验跳转 PF=0

1) 相等性的比较

下表列出了基于相等性评估的跳转指令。有些情况下,进行比较的是两个操作数;其他情况下,则是基于 CX、ECX 或 RCX 的值进行跳转。表中符号 leftOp 和 rightOp 分别指的是 CMP 指令中的左(目的)操作数和右(源)操 作数:

助记符 说明
JE 相等跳转 (leftOp=rightOp)
JNE 不相等跳转 (leftOp M rightOp)
JCXZ CX=0 跳转
JECXZ ECX=0 跳转
JRCXZ RCX=0 跳转(64 位模式)
1
CMP leftOp,rightOp

操作数名字反映了代数中关系运算符的操作数顺序。比如,表达式 X< Y 中,X 被称为 leftOp,Y 被称为 rightOp。

尽管 JE 指令相当于 JZ(为零跳转),JNE 指令相当于 JNZ(非零跳转),但是,最好是选择最能表明编程意图的助记符(JE 或 JZ),以便说明是比较两个操作数还是检查特定的状态标志位。

下述示例使用了 JE、JNE、JCXZ 和 JECXZ 指令。仔细阅读注释,以保证理解为什么条件跳转得以实现(或不实现)。

示例 1:

1
2
3
4
mov edx, 0A523h
cmp edx, 0A523h
jne L5 ;不发生跳转
je L1 ;跳转

示例 2:

1
2
3
4
mov bx,1234h
sub bx,1234h
jne L5 ;不发生跳转
je L1 ;跳转

示例 3:

1
2
3
mov ex, 0FFFFh
inc ex
jexz L2 ;跳转

示例4:

1
2
xor ecx,ecx
jeexz L2 ;跳转

2) 无符号数比较

基于无符号数比较的跳转如下表所示。操作数的名称反映了表达式中操作数的顺序(比如 leftOp < rightOp)。下表中的跳转仅在比较无符号数值时才有意义。有符号操作数使用不同的跳转指令。

助记符 说明 助记符 说明
JA 大于跳转(若 leftOp > rightOp) JB 小于跳转(若 leftOp < rightOp)
JNBE 不小于或等于跳转(与 JA 相同) JNAE 不大于或等于跳转(与 JB 相同)
JAE 大于或等于跳转(若 leftOp ≥ rightOp) JBE 小于或等于跳转(若 leftOp ≤ rightOp)
JNB 不小于跳转(与 JAE 相同) JNA 不大于跳转(与 JBE 相同)

3) 有符号数比较

下表列岀了基于有符号数比较的跳转。下面的指令序列展示了两个有符号数值的比较:

助记符 说明 助记符 说明
JG 大于跳转(若 leftOp > rightOp) JL 小于跳转(若 leftOp < rightOp)
JNLE 不小于或等于跳转(与 JG 相同) JNGE 不大于或等于跳转(与 JL 相同)
JGE 大于或等于跳转(若 leftOp ≥ rightOp) JLE 小于或等于跳转(若 leftOp ≤ rightOp)
JNL 不小于跳转(与 JGE 相同) JNG 不大于跳转(与 JLE 相同)
1
2
3
4
mov al, +127       ;十六进制数值 7Fh
cmp al, -128 ;十六进制数值 80h
ja Is Above ;不跳转,因为 7Fh < 80h
jg IsGreater ;跳转,因为 +127 > -128

由于无符号数 7Fh 小于无符号数 80h,因此,为无符号数比较而设计的 JA 指令不发生跳转。另一方面,由于 +127 大于 -128,因此,为有符号数比较而设计的 JG 指令发生跳转。

对下面的代码示例,阅读注释,以保证理解为什么跳转得以实现(或不实现):

示例 1:

1
2
3
4
5
mov edx,-1
cmp edx, 0
jnl L5 ;不发生跳转(-1 ≥ 0 为假)
jnle L5 ;不发生跳转(-1 > 0 为假)
jl L1 ;跳转(-1 < 0 为真)

示例 2:

1
2
3
4
5
mov bx,+ 32
cmp bx,-35
jng L5 ;不发生跳转( + 32 ≤ -35 为假)
jnge L5 ;不发生跳转( + 32 < -35 为假)
jge L1 ;跳转( + 32 ≥ -35 为真)

示例 3:

1
2
3
4
mov ecx, 0
cmp ecx, 0
jg L5 ;不发生跳转(0 > 0 为假)
jnl L1 ;跳转(0 ≥ 0 为真)

示例 4:

1
2
3
4
mov ecx, 0
cmp ecx, 0
jl L5 ;不发生跳转(0 < 0 为假)
jng L1 ;跳转(0 ≤ 0 为真)