2011-07-10 44 views
2

我有一个C++代码,它调用外部库中的函数。我调用的函数是CreateProcess,如下所示。混淆外部API调用C++

CreateProcess(NULL,pProcessName,NULL,NULL,false,CREATE_SUSPENDED, 
     NULL,NULL,&suStartUpInformation,&piProcessInformation) 

现在,当我编译代码和其拆解,组装展示了纯文本的CreateProcess(args1,args2,...)。是否有任何方法来混淆或加密函数调用API,以便如果有人将其分解,那么他永远不会知道哪些函数被调用。

谢谢!

+5

听起来像有人正在建造一个木马... – themaestro

+1

或更糟。你在西门子工作吗? :-) –

+0

你是对的我frend。它的某种AV旁路东西。但不是为了伤害,而是为了测试保护级别。 –

回答

3

任何通过名称导入的函数都会将名称嵌入到二进制文件中(在导入描述符thunk中是准确的),详细的参数信息是从Steve提到的pdbs获得的(不过分析像ollydbg这样的调试器可以由于符号名称可用,推导出参数)。避免这种情况的唯一方法是加密到IAT(使用第三方包装器/虚拟器/二元保护系统等,如enigma)或使用定制版本GetModuleHandle(基本上只是一个PEB spelunking工具)和GetProcAddress(PE探测工具然后通过将所需的所有api调用存储为运行时加密的字符串,然后可以调用任何您需要的内容,而不用纯文本将您带走(securerom会这样做,尽管直接使用GetProcAddress以及一些二进制混淆)。

更新:

了编译时“模糊”的字符串,你可以使用这样的事情(很简单,但它应该是便携式的,如果你使用的C++ 0x,这是一个容易得多):

#define c(x) char((x) - 1) //really simple, complexity is up to the coder 
#define un(x) char((x) + 1) 

typedef int (WINAPI* MSGBOX)(HWND, LPCSTR, LPCSTR, UINT); 
const int ORD_MASK = 0x10101010;  
const char szMessageBoxA[] = {c('M'),c('e'),c('s'),c('s'),c('a'),c('g'),c('e'),c('B'),c('o'),c('x'),c('A')}; 


FARPROC GetProcAddressEncrypted(HMODULE hModule, const char* szName, BOOL bOrd = FALSE) 
{ 
    if(bOrd) 
     return GetProcAddress(hModule,reinterpret_cast<const char*>(reinterpret_cast<int>(szName)^ORD_MASK)); //this requires that ordinals be stored as ordinal^ORD_MASK 

    char szFunc[128] = {'\0'}; 
    for(int i = 0; *szName; i++) 
     szFunc[i] = uc(*szName++); 

    return GetProcAddress(hModule,szName); 
} 

MSGBOX pfMsgBox = static_cast<MSGBOX>(GetProcAddressEncrypted(GetHandleEncrypted(szUser32),szMessageBox)); 

可选您可能希望使用MSVC的EncodePointer隐藏在全局函数指针的值(只记得使用DecodePointer当你给他们打电话)。

注:代码是未经测试,因为它只是把我的头

+0

有没有听说过按序输入? (尽管找到实际的函数名称仍然非常简单,但它不会存在于您的文件中)。 –

+0

@ben:是的,我有,但不是很多widows API(或其他API)通过序号输出,winsock和ole是少数几个做的。 – Necrolis

+0

谢谢! Necrolis,那么我不会使用任何第三方工具。我的问题很简单,你将如何在C++中对dll及其函数进行混淆调用,以使其不会在拆装器中显示。我通过调用User32.dll中的MessageBoxA函数找到了一个示例。该代码正在加载DLL,但没有正确调用该函数。请参阅下面的代码。 –

2

您可以使用动态链接的顶部。在Windows中,使用LoadLibrary,LoadLibraryEx,GetProcAddress。现在在你的代码中,包含一些形式为名称的混淆形式,而不是真正的lib /符号名称,并在运行时对其进行解密。

您可能希望使用动态分派(函数指针),以便所调用的函数无法从代码中轻松推导出来。

您可能会将调用此函数的工作委托给另一个线程(使用某种IPC机制)。

但是它很没用,使用调试器就会很简单的发现这个函数已经被调用了。检测到一个过程已经创建,这将非常简单。

+0

谢谢ysdx。你对答案非常不满。我使用你提到的LoadLibraryA&GetProcAddress。 –

0

好的!这里是解决方案。可以说我想从“user32.dll”调用“MessageBoxA”。 所以这里是我将如何使用LoadLibraryA & GetProcAddress

//Ok here you can see. 
//I am passing DLL name(user32.dll) and DLL function(MessageBoxA) as String 
//So I can also perform Encrypt & Decrypt operation on Strings and obfuscate it. 
//Like i can encrypt the string "user32.dll" and at runtime decrypt it and pass it as 
//an argument to "LoadLibraryA" and same for the Function name "MessageBoxA". 
//The code is compiled in DevC++ 4.9.9.2. 

#include <windows.h> 
#include <iostream> 
using namespace std; 

void HelloWorld() 
{ 
     char* szMessage = "Hello World!"; 
     char* szCaption = "Hello!"; 
     HMODULE hModule   = LoadLibraryA("user32.dll"); 
     FARPROC fFuncProc  = GetProcAddress(hModule, "MessageBoxA"); 
     ((int (WINAPI *)(HWND, LPCSTR, LPCSTR, UINT)) fFuncProc)(0, szMessage, szCaption, 0); 
} 
int main() 
{ 
    HelloWorld(); 
} 
+0

反汇编器/反编译器很简单,发现被调用的函数是MessageboxA。 – ysdx

+2

但不适用于十六进制编辑器..哈哈 –