从准备写壳到到现在已经有半年多的时间了,期间代码框架重构了很多次。
二、混淆地址管理器( 也叫全局地址管理器,因为vm框架也是用这个地址管理器 ) 在代码混淆过程中,你并不知道接下来的代码区块将会被膨胀到多大,所以必须要一个地址管理器来确定下一区块的大小。 首先要将地址分块,按照去除重定位(401000 处加载基址)的方式分配地址:
代码块1 : address 0x40B016
代码块2 : address xxx
代码块3:address xxx
使用地址管理器将代码块的地方分配并连接起来达到如下效果:
混淆分块后效果图:
1.区块划分
[DBGLOG]:代码块0,区块属性 JCC
mov eax, 0x1
cmp eax, 0x2
jz 0x40100e
[DBGLOG]:代码块1,区块属性 NULL
add eax, 0x1
inc eax
[DBGLOG]:代码块2,区块属性 JCC
mov eax, eax
add eax, 0x1
cmp eax, 0x1
jnz 0x40101d
[DBGLOG]:代码块3,区块属性 NULL
mov eax, eax
add eax, 0x1
[DBGLOG]:代码块4,区块属性 JCC
add eax, 0x1
dec eax
cmp eax, 0x2
jz 0x40102b
[DBGLOG]:代码块5,区块属性 NULL
mov eax, eax
add eax, 0x1
[DBGLOG]:代码块6,区块属性 JCC
mov eax, eax
mov eax, eax
dec eax
cmp eax, 0x3
jnz 0x40103a
[DBGLOG]:代码块7,区块属性 NULL
mov eax, eax
add eax, 0x1
[DBGLOG]:代码块8,区块属性 End
sub eax, 0x1
mov eax, eax
[DBGLOG] 地址:00401000,代码块:0
[DBGLOG] 地址:0040100a,代码块:1
[DBGLOG] 地址:0040100e,代码块:2
[DBGLOG] 地址:00401018,代码块:3
[DBGLOG] 地址:0040101d,代码块:4
[DBGLOG] 地址:00401026,代码块:5
[DBGLOG] 地址:0040102b,代码块:6
[DBGLOG] 地址:00401035,代码块:7
[DBGLOG] 地址:0040103a,代码块:8
先说一下总体架构共有三部分 1.PE部分 ,2.混淆虚拟化部分,3.保护部分
目前 PE部分只写了简单的操作,没有对代码段的压缩和对导入表的处理.
虚拟化部分 框架大概写蹦了5,6次(目前可以做到简单指令的模拟和对重定位的支持)最近一次是在2个月以前,将架构改成vmp 3.x的链式寻址的时候,又写蹦了框架,现在还没有整合
本帖就说一下近期在写的混淆部分
目前在写代码混淆膨胀部分,目前的设定框架是由3块组成:
1.代码块的拆分
2.全局地址管理器
3.混淆过程
一、代码块的拆分
二、混淆地址管理器( 也叫全局地址管理器,因为vm框架也是用这个地址管理器 ) 在代码混淆过程中,你并不知道接下来的代码区块将会被膨胀到多大,所以必须要一个地址管理器来确定下一区块的大小。 首先要将地址分块,按照去除重定位(401000 处加载基址)的方式分配地址:
代码块1 : address 0x40B016
代码块2 : address xxx
代码块3:address xxx
使用地址管理器将代码块的地方分配并连接起来达到如下效果:
混淆分块后效果图:
三、混淆过程步骤:
使用
代码块的拆分 + 地址管理器 -> 将代码块划分成一个个小的地址快来进行管理
首先划分区块,并将区块打上属性标签
1.区块划分
[DBGLOG]:代码块0,区块属性 JCC
mov eax, 0x1
cmp eax, 0x2
jz 0x40100e
[DBGLOG]:代码块1,区块属性 NULL
add eax, 0x1
inc eax
[DBGLOG]:代码块2,区块属性 JCC
mov eax, eax
add eax, 0x1
cmp eax, 0x1
jnz 0x40101d
[DBGLOG]:代码块3,区块属性 NULL
mov eax, eax
add eax, 0x1
[DBGLOG]:代码块4,区块属性 JCC
add eax, 0x1
dec eax
cmp eax, 0x2
jz 0x40102b
[DBGLOG]:代码块5,区块属性 NULL
mov eax, eax
add eax, 0x1
[DBGLOG]:代码块6,区块属性 JCC
mov eax, eax
mov eax, eax
dec eax
cmp eax, 0x3
jnz 0x40103a
[DBGLOG]:代码块7,区块属性 NULL
mov eax, eax
add eax, 0x1
[DBGLOG]:代码块8,区块属性 End
sub eax, 0x1
mov eax, eax
2.将代码区块使用地址管理器分配地址:
[DBGLOG] 地址:00401000,代码块:0
[DBGLOG] 地址:0040100a,代码块:1
[DBGLOG] 地址:0040100e,代码块:2
[DBGLOG] 地址:00401018,代码块:3
[DBGLOG] 地址:0040101d,代码块:4
[DBGLOG] 地址:00401026,代码块:5
[DBGLOG] 地址:0040102b,代码块:6
[DBGLOG] 地址:00401035,代码块:7
[DBGLOG] 地址:0040103a,代码块:8
3.添加简易重定位支持:
这里对于混淆引擎来说使用到的全局变量应该交由PE部分去处理,但我这边偷懒直接使用vmp的重定位方式(/尴尬)
4.指令处理:
对于混淆虚拟化来说代码的本质是等价替换,这里以举一个最简单的例子
push
0x123456
:
我的方式 主要是对0x123456 进行处理,首先拿到0x123456 这个立即数 对0x123456进行加法,
异或 等操作 imm = ( 0x123456+0x111111 ) ^ 0x22222 = 0x216745在混淆代码中表现出来:
push eax
mov eax,imm
xor eax,0x22222
sub eax,0x111111
push eax
mov eax,dword ptr[esp+0x4]
这样就完成了 对 push 0x123456 指令的混淆。
5.花指令的插入
在全局 有一个控制花指令插入的开关 _flower_code 由它决定是否插入花指令,部分代码如下:
void CodeObfuscationEngine::_insert_flower_code(asmjit::X86Assembler *& _a)
{
if (_insert_junk_code_number % 100 > _flower_code)
return;
int r = rand() % 3;
switch (r)
{
case 0:
{
Label label = _a->newLabel();
_a->jmp(label);
_a->db(0xE8);
_a->bind(label);
}break;
case 1:
{
Label label = _a->newLabel();
_a->jmp(label);
_a->db(0xE9);
_a->bind(label);
}break;
case 2:
{
Label label = _a->newLabel();
int addr = rand() % 0x66 + 0x5;
_a->call(label);
_a->db(0x74);
_a->db(addr);
_a->bind(label);
_a->add(esp, 4);
}break;
default:
break;
}
正常代码块:
代码块拆分:
代码混淆部分+花部分 :
里面去除了对某些指令的膨胀(比方xor)相对比较简单,新手项可以看未加壳部分,要求是逆出key
CrackMe :
原始的未混淆部分:
写在最后:
自己的工程参考了很多很多代码(多到我也记不清了,就不一一署名),先谢谢前辈们无私的奉献。
目前很少看到在群里有人认真的讨论一些问题,基本都是在发图吹水,如果有人问一个技术性的问题,那么突然间整个群好像卡死一般的没人说话,过一段时间有个人试探性的往群里发了一张水图,整个群的气氛就又活跃起来,导致很多人的问题都得不到解答,所以我自己建了个小群,希望对加壳脱壳、vm虚拟机研究、膨胀指令还原的小伙伴能加群一起讨论问题,对我多多指点,谢谢。
群号是Crackme里面的key
1.PE部分 ,2.混淆虚拟化部分,3.保护部分
目前 PE部分只写了简单的操作,没有对代码段的压缩和对导入表的处理.
虚拟化部分 框架大概写蹦了5,6次(目前可以做到简单指令的模拟和对重定位的支持)最近一次是在2个月以前,将架构改成vmp 3.x的链式寻址的时候,又写蹦了框架,现在还没有整合
本帖就说一下近期在写的混淆部分
目前在写代码混淆膨胀部分,目前的设定框架是由3块组成:
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-3-24 20:34
被Wszzy编辑
,原因: