-
-
[原创]Vmprotect编译字节码的策略 - 真是太强了
-
发表于:
2007-4-14 00:40
7656
-
[原创]Vmprotect编译字节码的策略 - 真是太强了
char* str = "this is string!haha";
__declspec(naked) func2()
{
VMPBEGIN
MessageBox(0,"1","",MB_OK);
_asm
{
retn
}
VMPEND
}
DWORD tmp = 0;
DWORD Eeax = 0;
_declspec(naked) func3()
{
VMPBEGIN
_asm
{
mov eax,Eeax
jmp [eax]
}
VMPEND
}
_declspec(naked) func()
{
VMPBEGIN
goto begin;
rets:
func2();
goto ends;
begin:
_asm
{
lea ebx,rets
mov tmp,ebx
}
Eeax = (DWORD)&tmp;
_asm
{
jmp func3
}
ends:
_asm
{
retn
}
VMPEND
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD ss = Eeax;
func();
getchar();
return 0;
}
以为jmp [eax]这种方法可以刁难Vmprotect了.
没想到它更胜一筹..
再找看看还有没能强奸它的语法.
************************************************************************************************************
稍微变了下代码
VMPBEGIN
goto begin;
rets:
_asm
{
push func2
retn
}
goto ends;
begin:
_asm
{
lea ecx,rets
mov tmp,ecx
lea ebx,tmp
mov Eeax,ebx
mov eax,Eeax
jmp [eax]
}
ends:
_asm
{
retn
}
VMPEND
发现顺利的挂了.
原因如下.
vmprotect在解释call时会先判断是否有其他代码引用当前地址.当没有引用时就直接编译为字节码,有引用时就将call放在原处.其他地址引用时也就不会出现错误了.
而改为push func2时就想也没想的把这里编译为字节码了,后面的 jmp [eax] 理所当然的就出问题了.
如果说要让vmprotect连这种类似自修改代码都支持的话的确有点困难.
不过.VC编译switch代码时会出现
jmp [401000+ebx] 跳到case语句去.
像这种不知道vmprotect的支持性怎么样...
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)