Запутать внешние вызовы API C ++ - PullRequest
2 голосов
/ 10 июля 2011

У меня есть код на C ++, который вызывает функции из внешней библиотеки.Вызванная мною функция CreateProcess , как показано ниже.

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

Теперь, когда я компилирую код и разбираю его, сборка показывает простой текст как CreateProcess (args1, args2,...) .Есть ли какой-нибудь способ запутать или зашифровать вызов функции API, чтобы, если кто-то разобьет ее, он никогда не узнает, какие функции вызваны.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 10 июля 2011

Любая функция, которая импортируется по имени, всегда будет иметь имя, встроенное в двоичный файл (если быть точным, в дескриптор импорта thunk), подробная информация о параметрах получена из pdbs, как упомянул Стив (однако анализ отладчиков, таких как ollydbg, может вывести args, из-за доступного имени символа). Единственным способом избежать этого является либо шифрование в IAT (с использованием сторонних упаковщиков / виртуализаторов / бинарных систем защиты и т. Д., Например, enigma), либо использование пользовательской версии GetModuleHandle (в основном просто инструмент для написания PEB) и GetProcAddress ( PE spelunking tool на этот раз), затем, сохраняя все необходимые вызовы 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 при их вызове).

примечание: код не проверен, так как он находится на моей голове

2 голосов
/ 10 июля 2011

Вы можете использовать динамическое связывание.В Windows используйте LoadLibrary, LoadLibraryEx, GetProcAddress.Теперь в вашем коде, включите некоторую форму в запутанную форму имени вместо реальных имен lib / символов и разблокируйте ее во время выполнения.

Возможно, вы захотите использовать динамическую диспетчеризацию (указатели на функции), чтобы вызываемая функция не моглалегко выводится из кода.

Вы можете делегировать работу по вызову этой функции другому потоку (используя некоторый механизм IPC).

Но это совершенно бесполезно, с помощью отладчика это будет очень просточтобы найти, что эта функция была вызвана.И будет очень просто обнаружить, что процесс был создан.

1 голос
/ 12 июля 2011

Хорошо!вот решение.Допустим, я хочу вызвать «MessageBoxA» из «user32.dll».Вот как я это сделаю, используя 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...