常见反汇编技术
  geC5EbVNIqH7 2023年11月01日 106 0

一. 相同目标的跳转指令

当jz与jnz的目地地址相同时,此时相当于jmp,但是IDA会将jnz后面的指令(实际上不会执行的指令)进行反汇编,这个时候如果加上比如call(E8),jmp(E9)等字节指令,那么势必会导致反汇编出现问题。
这个时候我们需要将jnz后面的代码转化为数据,然后使正常跳转的位置转化为代码段。
例如:74 03 75 01 E8 58(4011c5) C3 90 90
对应汇编指令为:

jz loc_4011c4+1;
jnz loc_4011c4+1;
call near ptr 90D0D521h;

这里显然就是出现了问题,jz和jnz都是跳转至loc_4011c5,即至58 c3 90 90。
实际的汇编代码为:

pop eax;
retn;
nop;
nop;

也就是说这个E8(call)实际上应该是无用的数据,但是却被反汇编,我们的解决方法就是将这个字节改为数据类型。

二.固定条件的跳转指令

当条件一定满足时说明这条判断语句指令后面的代码一定处于可执行状态,那么false对应的指令一定不会执行,这个时候倘若出现反汇编错误就可以对false对应的指令进行修改。
例如:33 C0 74 01 E9(jmp) 58(4011c5) C3 68 94
汇编指令为:

xor eax,eax;
jz loc_4011c4+1;
jmp near ptr 94A8D521h;

这里jz是一定会跳转的所以E9是不会执行应该是从4011c5开始反汇编。
正确反汇编代码为:

xor eax,eax;
jz loc_4011c4+1;
pop eax;
retn;

三.无效的反汇编指令

流氓字节作为合法指令的一部分时,需要对字节码进行详细的分析,甚至是到底层分析。
例如:66 B8 EB(4011c2) 05 31 C0 74 FA E8(call) real code
汇编指令为:

mov ax, 05EBh;
xor eax,eax;
jz sub_4011c0+2;
call ;

这里实际上就是跳转之后为可执行代码的部分。
实际汇编代码流程:

mov ax, 05EBh;
xor eax,eax;
jz sub_4011c0+2;
jmp sub_4011c2+4;

这里就需要对这一段代码进行详细分析,判断这段代码实际产生的效果,然后使用脚本用nop指令替换无效指令。

四.混淆控制流图

1.函数指针问题:将函数指针放入寄存器或者堆栈当中,然后使用call调用对应函数,这样的话就没办法直接通过ctrl+x查看函数调用,但是这里可以通过查看对offset sub_4011c0的调用来进行分析。

mov [ebp+var_4], offset sub_4011c0;
push 2Ah;
call [ebp+var_4];

2.滥用返回指针

使用retn指令来实现函数调用

	var_4    =byte ptr -4;
4011c0	call $+5;//将4011c5压入栈中
4011c5	add [esp+4+var_4],5;//将栈转化为4011CA
4011c9	retn;//调用4011CA函数

4011ca push ebp;
...
...

这样的话就无法正常定位有关的函数调用

3.滥用结构化异常处理

结构化异常处理(SEH)是用于处理异常的一个函数列表,倘若遇上异常,会按照次序依次调用SEH当中的函数进行处理。当最后一个函数也无法处理的时候会弹出对话框进行报错,滥用结构化异常处理是指在SEH链当中加入自己定义的异常处理函数来实现控制流混淆。
由于SEH存放在栈中,最后放入的函数最先进行调用,所以可以通过压栈实现加入对应的函数,通过FS:[0]寄存器来进行寻址。
在FS段寄存器当中存储TEB,TEB当中第一个数据结构TIB的前八个字节是SEH数据结构链表。所以我们不用关心SEH链表当中的其他数据,只需要将要加入的SEH链表块加入SEH当中然后将fs:[0]寄存器指向对应地址即可。

struct _EXCEPTION_REGISTRATION
{
	DWORD prev;//指向前一个记录的指针
	DWORD handle;//指向异常处理函数的指针
}

//例如
push ExceptionalHandle;//将函数指针入栈
push fs:[0];//将上一条指令的指针入栈
mov fs:[0],esp;//fs:[0]寄存器指向SEH链表的最后一个也是最先调用的函数

实战例子:

mov eax, (offset loc_40106B+1);
add eax, 14h;
//这两句汇编代码就是实现异常处理函数的构建,实际异常处理函数为loc_401080
push eax;//函数压入栈中
push  large dword ptr fs:0;
mov large fs:0, esp;
//成功加入SEH异常处理函数
xor ecx, rcx;
div ecx;
//构建除0错误

但是怎么实现从异常处理函数返回至原函数操作位置尚不清楚,需要后续对SEH加强学习。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  5NWiQFAVeqgX   2024年05月17日   36   0   0 网络安全
  pTtIhLb24H2d   2024年05月17日   35   0   0 网络安全
  OKgNPeBk991j   2024年05月18日   48   0   0 网络安全
  rKgO6TN7xbYO   2024年05月17日   40   0   0 网络安全
  5NWiQFAVeqgX   2024年05月17日   53   0   0 网络安全
  5NWiQFAVeqgX   2024年05月17日   37   0   0 网络安全
  YOkriIV1Am1d   2024年05月20日   41   0   0 网络安全
  owpmXY9hzjPv   2024年05月20日   42   0   0 网络安全
  owpmXY9hzjPv   2024年05月20日   44   0   0 网络安全
  owpmXY9hzjPv   2024年05月20日   35   0   0 网络安全