2011-07-10 5 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

あなたは私のフレンドです。そのAVバイパスのもののいくつかの種類。しかし、害はないが保護レベルをテストする。 –

答えて

3

名前でインポートされた関数は、常にバイナリに埋め込まれた名前を持ちます(厳密にはインポート記述子ではサンク)。詳細なパラメータ情報はSteveが述べたようにpdbsから取得されます(ただしollydbgのようなデバッガシンボル名が利用可能であるため、argsを推論する)。これを避ける唯一の方法はIATに暗号化するか(Enigmaのようなサードパーティのパッカー/バーチャライザー/バイナリ保護システムなどを使用する)か、GetModuleHandle(基本的にはPEBのスピルツールです)と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)); 

オプションで、(ちょうどあなたがそれらを呼び出すときDecodePointerを使用することを忘れないでください)グローバル関数ポインタの値を非表示にするにはMSVCのEncodePointerを使用することもできます。

注:動的リンクを使用する場合がありますそのちょうど私の頭の上

+0

序文でのインポートについて聞いたことがありますか? (実際の関数名を見つけるのはまだ簡単ですが、ファイルには存在しません)。 –

+0

@ben:はい私は持っているが、非常に多くのwidows API(または他のAPI)を序数、winsock、およびoleでエクスポートすることはほとんどありません。 – Necrolis

+0

ありがとう! Necrolis、まあ、私はサードパーティのツールを使用するつもりはありません。私の質問は、あなたがdllとその関数をC++で難読化して、どのようにしてそれがdissemblerで明らかにされないようにするかという単純なものでした。 User32.dllのMessageBoxA関数を呼び出すことによって、例を見つけました。コードはdllをロードしていますが、関数を適切に呼び出すことはありません。以下のコードを参照してください。 –

2

オフとしてコードは、テストされていません。 Windowsでは、LoadLibrary、LoadLibraryEx、GetProcAddressを使用します。今度はコードで、実際のlib /シンボル名ではなく、難読化された形式のフォームにいくつかのフォームを組み込み、実行時にunofuscateします。

呼び出された関数をコードから簡単に推測できないように、動的ディスパッチ(関数ポインタ)を使用することができます。

(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

ただし、16進エディターはありません.haha –

関連する問題