隐藏api函数调用对于对付静态分析,不用说是非常有意义的,许多加壳软件在输入表上大做文章,其中有一个重要的作用就是让破解者在得到的反汇编代码中看不到正常的api函数调用。我做一个最简单的测试,在不借助加壳软件和虚拟机保护技术的情况下,用手写代码的方式来实现隐藏api函数调用。
先看看我要保护的代码:
#include "windows.h"
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
MessageBox(0,"Reverse Me","Test",0);
return 0;
}
#include "windows.h"
typedef int (WINAPI *MYFUNC)(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
char MsgBoxA[]={0x5c,0x74,0x62,0x62,0x70,0x76,0x74,0x53,0x7e,0x69,0x50,0x00}; //字符串"MessageBoxA"的加密形式。
char lpText[]={0x43,0x74,0x67,0x74,0x63,0x62,0x74,0x31,0x5C,0x74,0x00}; //字符串"Reverse Me"的加密形式。
char lpCaption[]={0x45,0x74,0x62,0x65,0x00}; //字符串"Test"的加密形式。
for(int i=0;i<strlen(MsgBoxA);i++) MsgBoxA[i]^=0x11; //解密字符串"MessageBoxA"
for(i=0;i<strlen(lpText);i++) lpText[i]^=0x11; //解密字符串"Reverse Me"
for(i=0;i<strlen(lpCaption);i++) lpCaption[i]^=0x11; //解密字符串"Test"
HMODULE hMod=LoadLibrary("user32.dll");
if(hMod)
{
MYFUNC func=(MYFUNC)GetProcAddress(hMod,MsgBoxA); //获取MessageBoxA的函数地址。
func(0,lpText,lpCaption,0); //调用MessageBoxA函数。
FreeLibrary(hMod);
}
return 0;
}
。。。。。。
MYFUNC func=NULL;
char * pFuncName;
HMODULE hMod=LoadLibrary("user32.dll");
if(hMod)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hMod;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((ULONG)hMod+pDosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader);
PIMAGE_DATA_DIRECTORY pExportData = (PIMAGE_DATA_DIRECTORY)(&(pOptionalHeader->DataDirectory[0]));
PIMAGE_EXPORT_DIRECTORY pExportTable = (PIMAGE_EXPORT_DIRECTORY)((ULONG)hMod+pExportData->VirtualAddress);
ULONG * AddrFunctions=(ULONG *)((ULONG)hMod+pExportTable->AddressOfFunctions);
ULONG * AddrNames=(ULONG *)((ULONG)hMod+pExportTable->AddressOfNames);
for(i=0;i<pExportTable->NumberOfFunctions;i++)
{
pFuncName=(char *)((LONG)hMod+AddrNames[i]);
if(strcmp(pFuncName,MsgBoxA)==0)
{
func=(MYFUNC)((LONG)hMod+AddrFunctions[i]);
break;
}
}
if(func)
func(0,lpText,lpCaption,0);
FreeLibrary(hMod);
}
。。。。。。
#pragma comment(linker, "/SECTION:.text,ERW")
void Decrypt(char * start,char * end)
{
for(char * i=start;i<end;i++)
{
(*i)^=0x11;
}
}
。。。。。。
Decrypt((char * )401000,(char * )400000); //两个需要更正的地址参数。
__asm inc eax __asm dec eax //16进制对应40 48 ,用来标记加密代码段起始地址
HMODULE hMod=LoadLibrary("user32.dll");
。。。。。。
__asm inc eax __asm dec eax //16进制对应40 48,用来标记加密代码段末地址
return 0;
。。。。。。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!