本文为看雪论坛精华文章
前言
分析vmp1.70.4
#include <Windows.h>
#include <iostream>
void __declspec(naked) test_vmp(int a, int b)
{
/*__asm {
mov eax,dword ptr[esp+4]
mov ecx,dword ptr[esp+8]
add eax,ecx
ret
}*/
__asm {
xor eax,ebx
xor eax, ebx
ret
}
}
int main()
{
test_vmp(1, 2);
printf("%d\n", x);
system("pause");
return 0;
}
//入口
00401080| jmp debug_test2.vmp.4A77D2 | Debug_test2.cpp:5
004A77D2| push 4A781400 |
004A77D7| call debug_test2.vmp.4A6B9F |
004A6B9F| jmp debug_test2.vmp.4A703A |
004A703A| push esi | esi:_mainCRTStartup
004A703B| jmp debug_test2.vmp.4A52E8 |
004A52E8| pushfd |
004A52E9| push D3AC6D6A |
004A52EE| mov byte ptr ss:[esp+4],8F |
004A52F3| pushfd |
004A52F4| pop dword ptr ss:[esp+4] | [esp+4]:___use_sse2_mathfcns+4A78
004A52F8| jmp debug_test2.vmp.4A64C1 |
004A64C1| call debug_test2.vmp.4A5FE9 |
004A5FE9| pushad |
004A5FEA| mov dword ptr ss:[esp+24],ebp | [esp+24]:_mainCRTStartup
004A5FEE| push esp |
004A5FEF| pushfd |
004A5FF0| push 72B57CE7 |
004A5FF5| pushfd |
004A5FF6| mov dword ptr ss:[esp+30],eax | eax:___use_sse2_mathfcns+2D1
004A5FFA| mov byte ptr ss:[esp],cl |
004A5FFD| call debug_test2.vmp.4A701F |
004A701F| call debug_test2.vmp.4A5A25 |
004A5A25| jmp debug_test2.vmp.4A6BC5 |
004A6BC5| mov dword ptr ss:[esp+34],edx | [esp+34]:___use_sse2_mathfcns+2D1
004A6BC9| call debug_test2.vmp.4A5C3D |
004A5C3D| call debug_test2.vmp.4A6681 |
004A6681| mov dword ptr ss:[esp+38],edx | [esp+38]:___use_sse2_mathfcns+2D1
004A6685| push dword ptr ss:[esp+8] | [esp+8]:___use_sse2_mathfcns+42C0
004A6689| mov dword ptr ss:[esp+38],ecx | [esp+38]:___use_sse2_mathfcns+2D1, ecx:___use_sse2_mathfcns+2D1
004A668D| push E7FE4EC3 |
004A6692| mov byte ptr ss:[esp],dh |
004A6695| lea esp,dword ptr ss:[esp+3C] |
004A6699| jmp debug_test2.vmp.4A632E |
004A632E| btr si,6 |
004A6333| push edi |
004A6334| push 20AD5139 |
004A6339| xchg esi,ecx | esi:_mainCRTStartup, ecx:___use_sse2_mathfcns+2D1
004A633B| call debug_test2.vmp.4A6129 |
004A6129| mov dword ptr ss:[esp+4],ebx |
004A612D| movsx esi,cl | esi:___use_sse2_mathfcns+2D1
004A6130| pop ecx | ecx:"U嬱Q梓\x0E"
004A6131| btc di,cx |
004A6135| pushad |
004A6136| mov dword ptr ss:[esp+1C],0 |
004A613E| stc |
004A613F| jmp debug_test2.vmp.4A70CF
004A70CF| mov esi,dword ptr ss:[esp+48] |
004A70D3| btr bp,sp |
004A70D7| jmp debug_test2.vmp.4A53AF |
004A53AF| movzx bp,bl |
004A53B3| btc bp,si |
004A53B7| rol esi,18 |
004A53BA| push 124E6496 |
004A53BF| inc esi |
004A53C0| jmp debug_test2.vmp.4A6C85 |
004A53F7 | rol ah,6 |
004A53FA | sbb edx,esp |
004A53FC | mov eax,dword ptr ss:[ebp] |
004A53FF | jmp debug_test2.vmp.4A5BC4
004A5BC4 | cmc |
004A5BC5 | mov edx,dword ptr ss:[ebp+4] |
004A5BC8 | push 25584F9E |
004A5BCD | pushad |
004A5BCE | clc |
004A5BCF | bt cx,C |
004A5BD4 | not eax |
004A5BD6 | pushad |
004A5BD7 | bt cx,bx |
004A5BDB | call debug_test2.vmp.4A5D63 |
004A5D63 | cmc |
004A5D64 | not edx |
004A5D66 | cmp edi,F7A6A772 |
004A5D6C | stc |
004A5D6D | stc |
004A5D6E | stc |
004A5D6F | and eax,edx |
004A5D71 | jmp debug_test2.vmp.4A5A3F |
004A5A3F | jmp debug_test2.vmp.4A6E72 |
004A6E73 | pushfd |
004A6E74 | mov dword ptr ss:[ebp+4],eax |
004A6E77 | jmp debug_test2.vmp.4A564D |
----------------------------------------------------------------------------------------------------------
//化简之后
004A53FC | mov eax,dword ptr ss:[ebp] |
004A5BC5 | mov edx,dword ptr ss:[ebp+4] |
004A5BD4 | not eax |
004A5D64 | not edx |
004A5D6F | and eax,edx |
004A6E74 | mov dword ptr ss:[ebp+4],eax |
004A6E77 | jmp debug_test2.vmp.4A564D |
IsDebuggerPresent
CheckRemoteDebuggerPresent
GetThreadContext
CloseHandle
NtQueryInformationProcess
NtSetInformationThread
//关于这些函数介绍,看雪里有很多大神发了反调试相关的帖子,搜一下就能找到。
#include <Windows.h>
#include <iostream>
int g_num = 0;
void __declspec(naked) test_vmp(int a, int b)
{
__asm {
mov eax,[esp+4] // [esp+4] == a
mov ebx,[esp+8] // [esp+8] == b
xor eax, ebx
mov g_num,eax
ret
}
}
void test2()
{
test_vmp(0x10, 0x21);
printf("%X\n", g_num);
}
int main()
{
test2();
system("pause");
return 0;
}
004A6AFF | 66:0FB6C3 | movzx ax,bl |
004A6B03 | F6D0 | not al |
004A6B05 | 66:0FB6C3 | movzx ax,bl |
004A6B09 | 66:0FBEC2 | movsx ax,dl |
004A6B0D | 8B45 00 | mov eax,dword ptr ss:[ebp] |
004A6B10 | 60 | pushad |
004A6B11 | E9 41140000 | jmp debug_test2.vmp.4A7F57 |
004A6A55 | 36:8B00 | mov eax,dword ptr ss:[eax] |
004A6A58 | 55 | push ebp |
004A6A59 | E9 8A000000 | jmp debug_test2.vmp.4A6AE8 |
004A6AE8 | 882C24 | mov byte ptr ss:[esp],ch |
004A6AEB | FF3424 | push dword ptr ss:[esp] |
004A6AEE | 8945 00 | mov dword ptr ss:[ebp],eax |
004A6AF1 | FF3424 | push dword ptr ss:[esp] |
004A6AF4 | 9C | pushfd |
004A6AF5 | 9C | pushfd |
004A6AF6 | 8D6424 38 | lea esp,dword ptr ss:[esp+38] |
004A6AFA | E9 83150000 | jmp debug_test2.vmp.4A8082 |
------------------------------------------------------
可以化简为:
004A6B0D | 8B45 00 | mov eax,dword ptr ss:[ebp] |
004A6A55 | 36:8B00 | mov eax,dword ptr ss:[eax] |
004A6AEE | 8945 00 | mov dword ptr ss:[ebp],eax |
可以把上面的handler块命名为Handler_Reg_Mem
004A6113 | push ebp |
004A6114 | lahf |
004A6115 | pushad |
004A6116 | mov eax,dword ptr ss:[ebp] |
004A6119 | rcr dh,6 |
004A611C | bts dx,7 |
004A6121 | bts dx,1 |
004A6126 | mov edx,dword ptr ss:[ebp+4] |
004A6129 | stc |
004A612A | not eax |
004A612C | pushfd |
004A612D | push dword ptr ss:[esp] |
004A6130 | not edx |
004A6132 | jmp debug_test2.vmp.4A66E3 |
004A6137 | not esi |
004A6139 | mov byte ptr ss:[esp],dh |
004A613C | pushfd |
004A613D | push C19B900A |
004A6142 | pushfd |
004A6143 | lea esp,dword ptr ss:[esp+4C] |
004A6147 | jmp debug_test2.vmp.4A60CA |
004A66E3 | clc |
004A66E4 | and eax,edx |
004A66E6 | push edi |
004A66E7 | push esi |
004A66E8 | jmp debug_test2.vmp.4A61EF |
004A61EF | mov dword ptr ss:[ebp+4],eax |
004A61F2 | mov byte ptr ss:[esp+C],31 | 31:'1'
004A61F7 | mov byte ptr ss:[esp+C],65 | 65:'e'
004A61FC | push A8B985C4 |
004A6201 | mov word ptr ss:[esp+C],sp |
004A6206 | pushfd |
004A6207 | pop dword ptr ss:[esp+34] |
004A620B | mov byte ptr ss:[esp+8],ah |
004A620F | call debug_test2.vmp.4A78E2 |
----------------------------------------------------------------------
//可以化简为:
004A6116 | mov eax,dword ptr ss:[ebp] |
004A6126 | mov edx,dword ptr ss:[ebp+4] |
004A612A | not eax |
004A6130 | not edx |
004A66E4 | and eax,edx |
004A61EF | mov dword ptr ss:[ebp+4],eax |
004A69C7 | 04 08 | add al,8 |
004A69C9 | 60 | pushad |
004A69CA | 66:05 7B36 | add ax,367B |
004A69CE | 8B45 00 | mov eax,dword ptr ss:[ebp] |
004A69D1 | 20D6 | and dh,dl |
004A69D3 | 66:F7D2 | not dx |
004A69D6 | 08C2 | or dl,al |
004A69D8 | 8B55 04 | mov edx,dword ptr ss:[ebp+4] |
004A69DB | 68 37EDD2A5 | push A5D2ED37 |
004A69E0 | 66:81FF 7052 | cmp di,5270 |
004A69E5 | 84CB | test bl,cl |
004A69E7 | F8 | clc |
004A69E8 | 83C5 08 | add ebp,8 |
004A69EB | FF7424 04 | push dword ptr ss:[esp+4] |
004A69EF | 66:896424 14 | mov word ptr ss:[esp+14],sp |
004A69F4 | E9 94F4FFFF | jmp debug_test2.vmp.4A5E8D |
004A5E8D | 8910 | mov dword ptr ds:[eax],edx |
004A5E8F | 9C | pushfd |
004A5E90 | 66:895424 04 | mov word ptr ss:[esp+4],dx |
004A5E95 | 8D6424 2C | lea esp,dword ptr ss:[esp+2C] |
004A5E99 | E9 E4210000 | jmp debug_test2.vmp.4A8082 |
-------------------------------------------------------------------------------
可以化简为:
004A69CE | 8B45 00 | mov eax,dword ptr ss:[ebp] |
004A69D8 | 8B55 04 | mov edx,dword ptr ss:[ebp+4] |
004A69E8 | 83C5 08 | add ebp,8 |
004A5E8D | 8910 | mov dword ptr ds:[eax],edx |
可以把上面的handler块命名为Handler_Mem_Reg
指令壳项目开源说明
#pragma once
#include <vector>
#include <basetsd.h>
using namespace std;
class AllocMemory
{
vector<char*>p;
public:
virtual ~AllocMemory()
{
for (int i = 0; i < p.size(); i++)
{
if (p[i]==0)
{
continue;
}
free(p[i]);
p[i] = 0;
}
p.clear();
}
public:
template<typename T>
T auto_malloc( ULONG_PTR MAXSIZE)
{
T tmp = (T)malloc(MAXSIZE);
memset((char*)tmp, 0, MAXSIZE);
p.push_back((char*)tmp);
return tmp;
}
};
void __declspec(naked) test_vmp(int a, int b)
{
__asm {
mov eax, [esp + 4]
mov eax, [esp + 4]
mov eax, [esp + 4]
mov eax,[esp+4] // [esp+4] == a
mov ebx,[esp+8] // [esp+8] == b
xor eax, ebx
mov g_num,eax
ret
}
}
int main()
{
test_vmp(1,2);
system("pause");
return;
}
//解析要保护的指令,翻译为中间表示
void MiddleRepresent(DISASM disAsm)
{
/*----------------------------------------------------------------------------------*/
/* 1、是否有操作3 */
/*----------------------------------------------------------------------------------*/
if (NO_ARGUMENT != disAsm.Argument3.ArgType)
{
switch (disAsm.Argument3.ArgType & 0xF0000000)
{
case REGISTER_TYPE: //寄存器
break;
case MEMORY_TYPE: //内存
break;
case CONSTANT_TYPE://常数
break;
default:
break;
}
}
/*----------------------------------------------------------------------------------*/
/* 2、是否有操作2 */
/*----------------------------------------------------------------------------------*/
if (NO_ARGUMENT != disAsm.Argument2.ArgType)
{
switch (disAsm.Argument2.ArgType & 0xF0000000)
{
case REGISTER_TYPE: //寄存器
break;
case MEMORY_TYPE: //内存
break;
case CONSTANT_TYPE://常数
break;
default:
break;
}
}
/*----------------------------------------------------------------------------------*/
/* 3、是否有操作1 */
/*----------------------------------------------------------------------------------*/
if (NO_ARGUMENT != disAsm.Argument1.ArgType)
{
switch (disAsm.Argument1.ArgType & 0xF0000000)
{
case REGISTER_TYPE: //寄存器
break;
case MEMORY_TYPE: //内存
break;
case CONSTANT_TYPE://常数
break;
default:
break;
}
}
/*----------------------------------------------------------------------------------*/
/* 4、处理普通handler */
/*----------------------------------------------------------------------------------*/
//省略...
/*----------------------------------------------------------------------------------*/
/* 5、判断是否有辅助handler */
/*----------------------------------------------------------------------------------*/
if (
0x10000000 != disAsm.Argument1.ArgType ||
0x10000000 != disAsm.Argument2.ArgType ||
0x10000000 != disAsm.Argument3.ArgType
)
{
if (NO_ARGUMENT != disAsm.Argument1.ArgType)
{
switch (disAsm.Argument1.ArgType & 0xF0000000)
{
case REGISTER_TYPE: //寄存器
break;
case MEMORY_TYPE: //内存
break;
case CONSTANT_TYPE://常数
break;
default:
break;
}
}
}
}
vPushReg VR_ecx //操作2
vPushReg VR_eax //操作1
vMOV //普通handler
vPopReg VR_eax //辅助handler
vPushReg VR_ecx //操作2
vPushReg VR_eax //操作1
vMOV //普通handler
vPopReg VR_eax //辅助handler
把VR_ecx、VR_eax、VR_eax分离出来保存在一个数据表的结构体中。
翻译就可以这样表示了:
vPushReg
vPushReg
vMOV
vPopReg
vPushReg //eax
vPushImm4 //4
vPushReg4 //ecx
vMUL_MEM //*
vPushReg4 //eax
vAdd4 //+
vPushImm4 //0x401000
vAdd //+
vWriteMemDs4
vPushImm4 //0xFFFFFFF8
vPushReg4 //ebp
vAdd4
负8会被BeaEngine引擎解析为0xFFFFFFF8,ebp-0x8与0xFFFFFFF8+ebp是等价的
void _declspec(naked) _stdcall code_vm_test(int x)
{
//MessageBoxA(NULL, 0, 0, 0);
_asm {
sub esp,0x150
push eax
push ecx
push edx
lea ecx, code_vm_test
add ecx,10h
push ecx
pop dword ptr[g_num + 4]
jmp L14
sub esp,0x150
L14:
mov ecx,1
xor eax,eax
mov ah,10h
mov bl,30h
L13:
add ecx,1
add ah,bl
cmp ecx,0x10
jle L13
//je L11
add eax,0x432
mov ebx,4
mov ecx,1
mov byte ptr[g_num + ebx + ecx * 4],ah
//mov word ptr[g_num + ebx + ecx * 4],ax
//mov dword ptr[g_num+ebx+ecx*4],eax
jmp L12
//L11:
mov g_num,eax
call test2
L12:
mov eax, 01h //eax=1:取CPU序列号
xor edx, edx
cpuid
mov acpuid, eax
mov dl,byte ptr[acpuid]
mov lcpuid, edx
pop edx
pop ecx
pop eax
add esp,0x150
retn 4
}
}
VMStartVM_2
vPushImm4
vPushReg4
vSUB4
vPopReg4
VCheckESP
vPushReg4
vPUSH
vPushReg4
vPUSH
vPushReg4
vPUSH
vPushImm4
vReadMemDs4
vPushReg4
vPopReg4
vPushImm4
vPushReg4
vAdd4
vPopReg4
vPushReg4
vPUSH
vRetnNOT_
vNotSimulate
vResumeStart_
vPushImm4
vJMP
vPushImm4
vPushImm4
vPushReg4
vSUB4
vPopReg4
VCheckESP
vPushImm4
vPushReg4
vMOV4
vPopReg4
vPushReg4
vPushReg4
vXOR4
vPopReg4
vPushImm4
vPushReg1_above
vMOV4
vPopReg1_above
vPushImm4
vPushReg1_low
vMOV4
vPopReg1_low
vPushImm4
vPushReg4
vAdd4
vPopReg4
vPushReg1_low
vPushReg1_above
vAdd4
vPopReg1_above
vPushImm4
vPushReg4
vCMP
vPushImm4
vJLE
vPushImm4
vPushImm4
vPushReg4
vAdd4
vPopReg4
vPushImm4
vPushReg4
vMOV4
vPopReg4
vPushImm4
vPushReg4
vMOV4
vPopReg4
vPushReg1_above
vPushImm4
vPushReg4
vMUL_MEM
vPushReg4
vAdd4
vPushImm4
vAdd4
vWriteMemDs1
vPushImm4
vJMP
vPushImm4
vPushReg4
vPushImm4
vWriteMemDs4
vPushImm4
vRetnNOT_
vCALL
vResumeStart_
vPushImm4
vPushReg4
vMOV4
vPopReg4
vPushReg4
vPushReg4
vXOR4
vPopReg4
vRetnNOT_
vNotSimulate
vResumeStart_
vPushReg4
vPushImm4
vWriteMemDs4
vPushImm4
vReadMemDs1
vPushReg1_low
vPopReg1_low
vPushReg4
vPushImm4
vWriteMemDs4
vPushReg4
vPopReg4
vPOP4
vPushReg4
vPopReg4
vPOP4
vPushReg4
vPopReg4
vPOP4
vPushImm4
vPushReg4
vAdd4
vPopReg4
VCheckESP
vPushImm4
vRETN
//生成垃圾指令
CString VMLoader2::ProduceRubbishOpecode(char* reg04, char* reg05)
{
VMTable vmtbl = vmtable32[SrandNum(0, m_vmlength)];
CString str = vmtbl.strInstruction;
//1、目的操作
switch (vmtbl.optype[0])
{
case NONETYPE://没有操作数
break;
case IMMTYPE://立即数
{
if (8 == vmtbl.bitnum[0])
{
str = str + " " + 4;
}
else if (16 == vmtbl.bitnum[0])
{
str = str + " " + 4;
}
else
{
str = str + " " + 8;
}
}
break;
case REGTYPE://寄存器
{
if (8 == vmtbl.bitnum[0])
{
for (int i = 0; i < 14; i++)
{
if (stricmp(reg04, regname_[2][i]) == 0)
{
str = str + " " + regname_[0][i];
break;
}
}
}
else if (16 == vmtbl.bitnum[0])
{
for (int i = 0; i < 14; i++)
{
if (stricmp(reg05, regname_[2][i]) == 0)
{
str = str + " " + regname_[1][i];
break;
}
}
}
else
{
str = str + " " + reg05;
}
}
break;
case MEMTYPE://内存
{//随机选择vmp1节中没有用到的内存
DWORD dnum = SrandNum(m_vmps.vmp1_startaddr+0x4000, m_vmps.vmp1_startaddr+0x5000);
CString memstr = dnum;
if (8 == vmtbl.bitnum[0])
{
str = str + " byte ptr[" + memstr.GetString() + "]";
}
else if (16 == vmtbl.bitnum[0])
{
str = str + " word ptr[" + memstr.GetString() + "]";
}
else
{
str = str + " dword ptr[" + memstr.GetString() + "]";
}
}
break;
default:
break;
}
//2、源操作数
switch (vmtbl.optype[1])
{
case NONETYPE://没有操作数
break;
case IMMTYPE://立即数
{
if (8 == vmtbl.bitnum[1])
{
str = str + "," + 4;
}
else if (16 == vmtbl.bitnum[1])
{
str = str + "," + 8;
}
else
{
str = str + "," + 4;
}
}
break;
case REGTYPE://寄存器(操作数2的寄存器可以在8个寄存器中任意选择)
{
if (0 == stricmp(vmtbl.strInstruction,"xchg"))
{//如果是xchg,寄存器则选择reg04,或者reg05
if (8 == vmtbl.bitnum[1])
{
for (int i = 0; i < 14; i++)
{
if (stricmp(reg05, regname_[2][i]) == 0)
{
str = str + "," + regname_[0][i];
break;
}
}
}
else if (16 == vmtbl.bitnum[1])
{
for (int i = 0; i < 14; i++)
{
if (stricmp(reg04, regname_[2][i]) == 0)
{
str = str + "," + regname_[1][i];
break;
}
}
}
else
{
str = str + "," + reg04;
}
break;
}
if (8 == vmtbl.bitnum[1])
{
str = str + "," + regname_[0][SrandNum(0, 8)];
}
else if (16 == vmtbl.bitnum[1])
{
str = str + "," + regname_[1][SrandNum(0, 8)];
}
else
{
str = str + "," + regname_[2][SrandNum(0, 8)];
}
}
break;
case MEMTYPE://内存
{//随机选择vmp1节内的地址,或者选esp寄存器
DWORD dnum = SrandNum(m_vmps.vmp1_startaddr, m_vmps.vmstartaddr);
CString memstr = dnum;
const char* memchr[5] = { memstr.GetString(),"esp+20","esp+28","esp+0x30","esp+0x14" };
const char* srandstr = memchr[SrandNum(0, 5)];
if (8 == vmtbl.bitnum[1])
{
str = str + ",byte ptr[" + srandstr + "]";
}
else if (16 == vmtbl.bitnum[1])
{
str = str + ",word ptr[" + srandstr + "]";
}
else
{
str = str + ",dword ptr[" + srandstr + "]";
}
}
break;
default:
break;
}
return str;
}
翻译为中间表示:
vPushReg4
vPushReg4
vXOR4
vPopReg4
CString vPushReg4(char* VR0, char* VR1)
{
CString str = "mov ";
str = str + VR0 +",dword ptr[ebp]\n" ;
str = str + "add ebp,4\n";
str = str + "xor " + VR0 + "," + dataencrypt + "\n";
str = str + "mov "+ VR0 +",dword ptr [edi+"+ VR0 +"*4]\n";
str = str + "push "+ VR0 +"\n";
return str;
}
CString vXOR4(char* VR0, char* VR1)
{
CString str = "mov ";
str = str + VR0 + ",dword ptr[esp]\n";
str = str + "mov " + VR1 + ",dword ptr[esp+4]\n";
str = str + "xor " + VR0 + "," + VR1 + "\n";
str = str + "add esp,8\n";
str = str + "push " + VR0 + "\n";
return str;
}
CString vPopReg4(char* VR0, char* VR1)
{
CString str = "mov ";
str = str + VR0 + ",dword ptr[ebp]\n";
str = str + "xor " + VR0 + "," + dataencrypt + "\n";
str = str + "add ebp,4\n";
str = str + "pop dword ptr[edi+" + VR0 + "*4]\n";
return str;
}
IAT加密过程:
第二步在Stub中解密这个临时数据结构,解密之后,再加密,并且加上花指令。
花指令构造器具体实现在JunkCode.cpp文件中。以下列出花指令构造器的核心函数:
//这是一个多跳、往回跳的花指令构造器,之后跳到真实指令。
void JunkCode_::SrandJunkCode()
{
BUFFERSTRUCT_ buffer;
buffer.value = jncode_one;
buffer.match = 1;
g_buffer.push_back(buffer);
buffer.value = buffer.match = 0;
g_buffer.push_back(buffer);
char x = jncode[rand_v() % 4];
buffer.value = x;
g_buffer.push_back(buffer);
if (x == 0xFF)
{
buffer.value = second[rand_v() % 2];
g_buffer.push_back(buffer);
}
int y = rand_v() % 3;
for (int i = 0; i < y; i++)
{
buffer.value = randsss[rand_v() % RANDSSS];
g_buffer.push_back(buffer);
}
buffer.value = jncode_one;
buffer.match = 0x3;
buffer.jmpmatch = 0x2;
g_buffer.push_back(buffer);
buffer.value = buffer.match = buffer.jmpmatch = 0;
g_buffer.push_back(buffer);
x = jncode[rand_v() % 4];
buffer.value = x;
g_buffer.push_back(buffer);
if (x == 0xFF)
{
buffer.value = second[rand_v() % 2];
g_buffer.push_back(buffer);
}
y = rand_v() % 3;
for (int i = 0; i < y; i++)
{
buffer.value = randsss[rand_v() % RANDSSS];
g_buffer.push_back(buffer);
}
for (int i = 0; i < 5; i++)
{
if (i == 0)
{
buffer.jmpmatch = 1;
buffer.recodemodify = 1;
buffer.value = moveax[i];
g_buffer.push_back(buffer);
buffer.jmpmatch = buffer.recodemodify = 0;
continue;
}
buffer.value = moveax[i];
g_buffer.push_back(buffer);
}
buffer.value = jncode_one;
buffer.match = 0x2;
g_buffer.push_back(buffer);
buffer.value = buffer.match = buffer.jmpmatch = 0;
g_buffer.push_back(buffer);
x = jncode[rand_v() % 4];
buffer.value = x;
g_buffer.push_back(buffer);
if (x == 0xFF)
{
buffer.value = second[rand_v() % 2];
g_buffer.push_back(buffer);
}
y = rand_v() % 2;
for (int i = 0; i < y; i++)
{
buffer.value = randsss[rand_v() % RANDSSS];
g_buffer.push_back(buffer);
}
for (int i = 0; i < 7; i++)
{
if (i == 0)
{
buffer.jmpmatch = 3; //3
buffer.value = jmpoep[i];
g_buffer.push_back(buffer);
buffer.match = buffer.jmpmatch = 0;
continue;
}
buffer.value = jmpoep[i];
g_buffer.push_back(buffer);
}
//修复数据
vector_< BUFFERSTRUCT_>::iterator iter_buff = g_buffer.begin();
vector_< BUFFERSTRUCT_>::iterator iter_buff_1 = g_buffer.begin();
for (int i = 0; i < g_buffer.size(); i++)
{
if ((*iter_buff).match != 0)
{
int temp = (*iter_buff).match;
for (int j = 0; j < g_buffer.size(); j++)
{
if (temp == (*iter_buff_1).jmpmatch)
{
(*(iter_buff + 1)).value= j - i - 2;
iter_buff_1 = g_buffer.begin();
break;
}
++iter_buff_1;
}
}
++iter_buff;
}
}
第一步:
第三步:
本文附件可点击左下角阅读原文自行下载!
看雪ID:舒默哦
https://bbs.pediy.com/user-home-877885.htm
*本文由看雪论坛 舒默哦 原创,转载请注明来自看雪社区。
《安卓高级研修班》2021年6月班火热招生中!
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!