Con alta calidad te pasa lo que a mi en C jeje:

GDI+ no le dá tregua a la CPU
. Notaste mucho aumento de velocidad al actualizar la pantalla por trozos?
Buen código
.

GDI+ no le dá tregua a la CPU

Buen código

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.
Mostrar Mensajes MenúCita de: Nakp en 30 Enero 2010, 00:45 AM
en realidad pueden darse permisos para mover/eliminar post propios pero no por foros, o al menos no he encontrado esa opcion xD asi que el problema no sería si mueven "borradores" de otros usuarios, sino que podria mover sus post en cualquier foro
pide entrar en el grupo colaborador mejor
Cita de: Karcrack en 16 Enero 2010, 22:13 PM
Tiene algun error?![]()
![]()
ClsHookAPI Hook;
Hook.SetHookedProcessName("ejecutable.exe");
int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
//Llamamos a MessageBoxA normalmente, cambiando el mensaje que muestra
return MessageBoxA(0,"MessageBoxA Hookeada!!!",lpCaption,0);
}
Hook<<"USER32.MessageBoxA";
Hook>>(unsigned long)HookedMessageBoxA;
#pragma comment (linker,"/ENTRY:main")
#include "ClsHookApi.h"
int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
void __stdcall HookedExitProcess(UINT uExitCode);
BOOL __stdcall HookedBeep(DWORD dwFreq,DWORD dwDuration);
int main()
{
ClsHookAPI miHook;
if(miHook.SetHookedProcessName("mensaje.exe"))
{
miHook<<"USER32.MessageBoxA";
miHook>>(unsigned long)HookedMessageBoxA;
miHook<<"KERNEL32.ExitProcess";
miHook>>(unsigned long)HookedExitProcess;
miHook<<"KERNEL32.DLL.Beep";
miHook>>(unsigned long)HookedBeep;
}
return 0;
}
int __stdcall HookedMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
return MessageBoxA(0,"MessageBoxA Hookeada!!!",lpCaption,0);
}
void __stdcall HookedExitProcess(UINT uExitCode)
{
MessageBoxA(0,"Has llamado a ExitProcess!","xD",0);
return ExitProcess(uExitCode);
}
BOOL __stdcall HookedBeep(DWORD dwFreq,DWORD dwDuration)
{
Beep(1000,100);
Beep(1000,100);
return Beep(1000,100);
}
//----------------------------------------------------------------------------------------------------
//Autor: Hacker_Zero
//Fecha: 11 enero 2010
//Nombre: ClsHookApi
//Descripción:
// Clase en C++ que permite hookear API's de forma simultánea, facilitando enormemente
//la programación de las funciones que reciven el hook así como la instalación de los
//propios hooks.
//----------------------------------------------------------------------------------------------------
//Código liberado bajo la GNU Public License (GPL) <http://www.gnu.org/licenses/gpl-3.0.html>
//Eres libre de utilizar, modificar y distribuír ésta clase siempre que mantengas ésta cabecera
//----------------------------------------------------------------------------------------------------
#include <windows.h>
#include <Tlhelp32.h>
#include <vector>
#include <string.h>
using namespace std;
struct HookStruct
{
LPSTR lpAPI;
LPSTR lpHookFunction;
CHAR lpBuffer[11];
HookStruct* previousHookStruct;
HookStruct* nextHookStruct;
};
#ifndef HOOKAPI_H
#define HOOKAPI_H
void HookApi(HookStruct* miHookStruct);
void mCopyMemory(LPSTR bEscritura,LPSTR bLectura,DWORD lenBuffer);
void ControlFunction();
void Caller();
void UninstallHooks(HookStruct* miHookStruct);
void RestoreHooks(HookStruct* miHookStruct);
class ClsHookAPI
{
public:
ClsHookAPI();
ClsHookAPI& operator<<(LPSTR HookName);
ClsHookAPI& operator>>(unsigned long lpFunctionHook);
bool SetHookedProcessName(LPSTR ProcessName);
private:
void AddFunction(HookStruct miHookStruct);
void InstallHook(HookStruct* miHookStruct);
vector<HookStruct> Hooks;
BOOL ExeInjected;
HANDLE hProcess;
LPSTR InjectedExeBaseAddress;
HookStruct* lastInjectedHookStruct;
};
#endif
#include "ClsHookApi.h"
//Constructor de la clase
ClsHookAPI::ClsHookAPI()
{
InjectedExeBaseAddress=NULL;
lastInjectedHookStruct=NULL;
ExeInjected=false;
}
//Sobrecarga del operador '<<'
ClsHookAPI& ClsHookAPI::operator<<(LPSTR HookName)
{
//Obtenemos la DLL y la API de HookName
string strHookName;
strHookName.append(HookName);
string strDllName=strHookName.substr(0,strHookName.find_last_of("."));
string strApiName=strHookName.substr(strHookName.find_last_of(".")+1);
//Inicializamos la estructura y seteamos el puntero a la API
HookStruct miHookStruct;
miHookStruct.lpAPI=(LPSTR)GetProcAddress(LoadLibraryA(strDllName.c_str()),strApiName.c_str());
//Añadimos la estructura al Array
AddFunction(miHookStruct);
return *this;
}
//Sobrecarga del operador '>>'
ClsHookAPI& ClsHookAPI::operator>>(unsigned long lpFunctionHook)
{
Hooks.back().lpHookFunction=(LPSTR)lpFunctionHook;
InstallHook(&Hooks.back());
return *this;
}
void ClsHookAPI::AddFunction(HookStruct miHookStruct)
{
//Si es el primer elemento que añadimos
if(!Hooks.size())
{
miHookStruct.previousHookStruct=NULL;
}
else
{
miHookStruct.previousHookStruct=this->lastInjectedHookStruct;
}
miHookStruct.nextHookStruct=NULL;
//Insertamos la estructura en el array
Hooks.push_back(miHookStruct);
return;
}
//Seteamos el nombre del proceso en el que inyectaremos
bool ClsHookAPI::SetHookedProcessName(LPSTR ProcessName)
{
HANDLE bakhProcess=hProcess;
hProcess=NULL;
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 pInfo;
pInfo.dwSize=sizeof(PROCESSENTRY32);
//Obtenemos el PID del proceso
Process32First(hSnapshot,&pInfo);
for(;Process32Next(hSnapshot,&pInfo);)
{
if(!lstrcmpA(pInfo.szExeFile,ProcessName))
{
if(OpenProcess(PROCESS_ALL_ACCESS,FALSE,pInfo.th32ProcessID))
{
ExeInjected=false;
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pInfo.th32ProcessID);
}
}
}
if(!hProcess)
{
hProcess=bakhProcess;
return false;
}
return true;
}
void ClsHookAPI::InstallHook(HookStruct* miHookStruct)
{
//Nos inyectamos en el proceso si no lo hemos hecho ya
if(ExeInjected==false)
{
PIMAGE_DOS_HEADER IDH;
PIMAGE_NT_HEADERS INTH;
PIMAGE_SECTION_HEADER ISH;
LPSTR lpFileName=(LPSTR)GlobalAlloc(GPTR,MAX_PATH);
GetModuleFileName(NULL,lpFileName,MAX_PATH);
HANDLE hFile=CreateFileA(lpFileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
DWORD szFile=GetFileSize(hFile,0);
DWORD dwBytes;
LPSTR lpFileMaped=(LPSTR)GlobalAlloc(GPTR,szFile);
ReadFile(hFile,lpFileMaped,szFile,&dwBytes,0);
CloseHandle(hFile);
//Obtenemos la cabecera DOS y PE en las estructuras
IDH=(PIMAGE_DOS_HEADER)&lpFileMaped[0];
INTH=(PIMAGE_NT_HEADERS)&lpFileMaped[IDH->e_lfanew];
//Creamos el buffer del tamaño del SizeOfImage en el que cargaremos el ejecutable
LPSTR ExeBuffer=(LPSTR)VirtualAllocEx(this->hProcess,0,INTH->OptionalHeader.SizeOfImage,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
//Copiamos la cabecera DOS y PE al buffer
WriteProcessMemory(this->hProcess,&ExeBuffer[0],&lpFileMaped[0],INTH->OptionalHeader.SizeOfHeaders,0);
//Copiamos las secciones en su VirtualOffset en el buffer
for(DWORD i=0;i<INTH->FileHeader.NumberOfSections;i++)
{
ISH=(PIMAGE_SECTION_HEADER)&lpFileMaped[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i];
WriteProcessMemory(this->hProcess,&ExeBuffer[ISH->VirtualAddress],&lpFileMaped[ISH->PointerToRawData],ISH->SizeOfRawData,0);
}
//Calculamos el delta entre la dirección del buffer y el ImageBase
DWORD Delta=(((DWORD)ExeBuffer)-INTH->OptionalHeader.ImageBase);
//------------------------------------------------------------
/* -Reubicamos la dirección base del ejecutable :D- */
//------------------------------------------------------------
//Obteemos el Image Base Relocation
//Copiamos el Image Base Relocation de los datos en el proceso a un buffer en el nuestro para
//poder trabajar con él más comodamente
PIMAGE_BASE_RELOCATION IBR=(PIMAGE_BASE_RELOCATION)GlobalAlloc(GPTR,sizeof(IMAGE_BASE_RELOCATION));
PIMAGE_BASE_RELOCATION PIBR=(PIMAGE_BASE_RELOCATION)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
ReadProcessMemory(hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0);
//Vamos recorriendo todas las etradas del bloque
for(DWORD n=0;IBR->VirtualAddress>0;n++)
{
//Obtenemos el Bloque de reubicación
LPSTR RelocationBlock=(LPSTR)(ExeBuffer+IBR->VirtualAddress);
//Obtenemos la primera entrada del bloque
LPWORD RelocationEntry=(LPWORD)((LPSTR)PIBR+sizeof(IMAGE_BASE_RELOCATION));
//Recorremos todas las entradas del bloque
for(DWORD i=0;i<((IBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2);i++,RelocationEntry++)
{
WORD valor;
ReadProcessMemory(this->hProcess,RelocationEntry,&valor,2,0);
//Obtenemos los 4 bits que definen el tipo de reubicación
DWORD type=valor>>12;
//Obtenemos los 12 bits que definen la dirección de la reubicación
DWORD offset=valor&0xFFF;
//Si el tipo de reubicación es relativo a la dirección base, añadimso el delta
if(type==IMAGE_REL_BASED_HIGHLOW)
{
//Añadimos a la dirección que depende del imagebase original
//el delta entre el imagebase y nuestra dirección base
LPDWORD newAddr=(LPDWORD)(RelocationBlock+offset);
DWORD NewValue;
ReadProcessMemory(this->hProcess,newAddr,&NewValue,4,0);
NewValue+=Delta;
WriteProcessMemory(this->hProcess,newAddr,&NewValue,4,0);
}
}
//Vamos al siguiente bloque
PIBR=(PIMAGE_BASE_RELOCATION)(((DWORD)PIBR)+IBR->SizeOfBlock);
ReadProcessMemory(this->hProcess,(LPVOID)PIBR,IBR,sizeof(IMAGE_BASE_RELOCATION),0);
}
GlobalFree(IBR);
//---------------------------------------------------------------------
/* -Cargamos los valores de la IAT para poder llamar a las API's- */
//---------------------------------------------------------------------
PIMAGE_THUNK_DATA ITD;
PIMAGE_THUNK_DATA PITD;
PIMAGE_IMPORT_BY_NAME IIBN;
//Comprobamos si hay Import Data Descriptor
if(INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size>0)
{
//Obtenemos el Import Data Descriptor
//Copiamos el Import Data Descriptor de los datos en el proceso a un buffer en el nuestro para
//poder trabajar con él más comodamente
PIMAGE_IMPORT_DESCRIPTOR IID=(PIMAGE_IMPORT_DESCRIPTOR)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_DESCRIPTOR));
PIMAGE_IMPORT_DESCRIPTOR PIID=(PIMAGE_IMPORT_DESCRIPTOR)(ExeBuffer+INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
ReadProcessMemory(this->hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0);
//Vamos recorriendo todas las Dll's importadas por el ejecutable
for(;IID->Name;)
{
//Obtenemos la longitud del nombre de la dll
DWORD szName=0;
CHAR miByte=1;
for(int i=0;miByte;i++)
{
szName=i;
ReadProcessMemory(this->hProcess,ExeBuffer+IID->Name+i,&miByte,1,0);
}
//Obtenemos el nombre de la dll
LPSTR lpName=(LPSTR)GlobalAlloc(GPTR,szName+1);
ReadProcessMemory(this->hProcess,ExeBuffer+IID->Name,lpName,szName+1,0);
//Cargamos la dll
HMODULE hLib=LoadLibraryA(lpName);
//Obtenemos la dirección al primer miembro del array Image Thunk Data's
PITD=(PIMAGE_THUNK_DATA)((DWORD)ExeBuffer+IID->FirstThunk);
ITD=(PIMAGE_THUNK_DATA)GlobalAlloc(GPTR,sizeof(IMAGE_THUNK_DATA));
ReadProcessMemory(this->hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0);
//Vamos recorriendo las funciones importadas
for(DWORD x=0;ITD->u1.Ordinal;x++)
{
miByte=1;
//Obtenemos la longitud del nombre de la API
for(int i=0;miByte;i++)
{
szName=i;
LPSTR puntero=ExeBuffer+ITD->u1.Function+2;
puntero+=i;
ReadProcessMemory(this->hProcess,puntero,&miByte,1,0);
}
//Cargamos el Image Import By Name para obtener el nombre
IIBN=(PIMAGE_IMPORT_BY_NAME)GlobalAlloc(GPTR,sizeof(IMAGE_IMPORT_BY_NAME)+szName);
ReadProcessMemory(this->hProcess,ExeBuffer+ITD->u1.Function,IIBN,sizeof(IMAGE_IMPORT_BY_NAME)+szName,0);
//Obtenemos la dirección de la función y la guardamos en la IAT
DWORD lpAPI=(DWORD)GetProcAddress(hLib,(LPCSTR)&IIBN->Name);
WriteProcessMemory(this->hProcess,ExeBuffer+IID->FirstThunk+x*sizeof(IMAGE_THUNK_DATA),&lpAPI,4,0);
PITD++;
ReadProcessMemory(this->hProcess,PITD,ITD,sizeof(IMAGE_THUNK_DATA),0);
}
PIID++;
ReadProcessMemory(this->hProcess,(LPVOID)PIID,IID,sizeof(IMAGE_IMPORT_DESCRIPTOR),0);
GlobalFree(lpName);
GlobalFree(ITD);
}
GlobalFree(IID);
}
this->InjectedExeBaseAddress=ExeBuffer;
this->ExeInjected=true;
}
//Cambiamos el ImageBase a la dirección de la función que recibe el hook
miHookStruct->lpHookFunction=(LPSTR)((unsigned long)this->InjectedExeBaseAddress+(unsigned long)miHookStruct->lpHookFunction-(unsigned long)GetModuleHandle(NULL));
//Reservamos espacio para la estructura en el proceso en el que inyectamos
HookStruct* lpHookStruct=(HookStruct*)VirtualAllocEx(this->hProcess,0,sizeof(HookStruct),MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
//Esribimos la estructura en el espacio reservado
WriteProcessMemory(this->hProcess,lpHookStruct,miHookStruct,sizeof(HookStruct),0);
//Seteamos el valor de nextHookStruct de la HookStruct anterior a la que acabamos de inyectar
HookStruct* lastHookStruct=(HookStruct*)GlobalAlloc(GPTR,sizeof(HookStruct));
ReadProcessMemory(this->hProcess,lastInjectedHookStruct,lastHookStruct,sizeof(HookStruct),0);
lastHookStruct->nextHookStruct=lpHookStruct;
WriteProcessMemory(this->hProcess,lastInjectedHookStruct,lastHookStruct,sizeof(HookStruct),0);
//Seteamo el valor de lastInjectedHookStruct
this->lastInjectedHookStruct=lpHookStruct;
//Obteemos la dirección de la función HookApi
DWORD lpHookApi=(DWORD)this->InjectedExeBaseAddress+(DWORD)HookApi-(DWORD)GetModuleHandle(NULL);
//Llamamos al EntryPoint
CreateRemoteThread(this->hProcess,0,0,(LPTHREAD_START_ROUTINE)lpHookApi,(HookStruct*)lpHookStruct,0,0);
return;
}
//Pequeño código en ASM que por el cual sustituimos el comienzo de la API
void __declspec(naked) Caller()
{
__asm
{
push 0x00400000 //~Ésta dirección se sustituye en tiempo de ejecución por el puntero a HookStruct
push 0x00400000 //~Ésta dirección se sustituye en tiempo de ejecución por la dirección de ControlFunction
ret
}
}
void UninstallHooks(HookStruct* miHookStruct)
{
__asm pushad;
//Nos desplazamos al primer Hook
for(;miHookStruct->previousHookStruct!=NULL;)
{
miHookStruct=miHookStruct->previousHookStruct;
}
//Desinstalamos todos los Hooks
for(;miHookStruct!=NULL;)
{
mCopyMemory(miHookStruct->lpAPI,miHookStruct->lpBuffer,11);
FlushInstructionCache(GetCurrentProcess(),0,0);
miHookStruct=miHookStruct->nextHookStruct;
}
__asm popad;
}
void RestoreHooks(HookStruct* miHookStruct)
{
__asm pushad;
//Nos desplazamos al primer Hook
for(;miHookStruct->previousHookStruct!=NULL;)
{
miHookStruct=miHookStruct->previousHookStruct;
}
//Volvemos a instalar todos los Hooks
for(;miHookStruct!=NULL;)
{
//Copiamos los X primeros bytes de la api a nuestro buffer
mCopyMemory(miHookStruct->lpBuffer,miHookStruct->lpAPI,11);
//Cambiamos los la primera dirección que pushea 'Caller' por la un puntero a miHookStruct
mCopyMemory((LPSTR)Caller+1,(LPSTR)&miHookStruct,4);
//Cambiamos los la segunda dirección que pushea 'Caller' por la dirección de ControlFunction
LPSTR dirControlFunction=(LPSTR)ControlFunction;
mCopyMemory((LPSTR)Caller+6,(LPSTR)&dirControlFunction,4);
//Cambiamos los 10 primeros bytes de la API por la función Caller
mCopyMemory(miHookStruct->lpAPI,(LPSTR)Caller,11);
FlushInstructionCache(GetCurrentProcess(),0,0);
miHookStruct=miHookStruct->nextHookStruct;
}
__asm popad;
}
//Función a la que salta la API hookeda en que se inyectó 'Caller'
void __declspec(naked) ControlFunction()
{
__asm
{
jmp go
miHookStruct:
nop
nop
nop
nop
retornar:
_emit 0x68 //push
dirRetorno:
nop
nop
nop
nop
_emit 0xC3 //ret
RetornoApi:
nop
nop
nop
nop
Temp:
nop
nop
nop
nop
go:
//Sólo modificamos eax para no modificar más registros de los que modifica la API
//Copiamos a Temp el primer parámetro que hay sobre la pila (lpHookStruct)
mov eax,Temp
push dword ptr ds:[esp]
pop dword ptr ds:[eax]
//Copiamos lpHookStruct a miHookStruct
push 4
push Temp
push miHookStruct
call mCopyMemory
add esp,12 //Restauramos la pila
//Quitamos lpHookStruct de la pila
add esp,4
//Copiamos a Temp el primer parámetro que hay sobre la pila (dirección de retorno)
mov eax,Temp
push dword ptr ds:[esp]
pop dword ptr ds:[eax]
//Copiamos la dirección de retorno a dirRetorno
push 4
push Temp
push dirRetorno
call mCopyMemory
add esp,12 //Restauramos la pila
//Quitamos la direcc de retorno de la pila
add esp,4
//LLamamos a UninstallHooks para desinstalar todos los hooks antes de llamar a la función que recive el Hook
mov eax,miHookStruct
push dword ptr ds:[eax]
call UninstallHooks
add esp,4
//Llamamos a la función que recive el hook y copiamos el retorno a RetornoApi
mov eax,miHookStruct
mov eax,dword ptr ds:[eax]
call dword ptr ds:[eax+0x04]
push eax
mov eax,RetornoApi
pop dword ptr ds:[eax]
//Restauramos todos los Hooks
mov eax,miHookStruct
push dword ptr ds:[eax]
call RestoreHooks
add esp,4
//Movemos a eax el retorno de la API
mov eax,RetornoApi
push dword ptr ds:[eax]
pop eax
//Saltamos a la dirección de retorno
jmp retornar
}
}
void HookApi(HookStruct* miHookStruct)
{
__asm pushad;
//Damos permisos de escritura, lectura y ejecución a nuestro buffer
DWORD OldProtection;
VirtualProtect((LPVOID)miHookStruct->lpBuffer,11,PAGE_EXECUTE_READWRITE,&OldProtection);
// Le damos permisos de ejecución a los X primeros bytes de la api
VirtualProtect((LPVOID)miHookStruct->lpAPI,11,PAGE_EXECUTE_READWRITE,&OldProtection);
//Copiamos los X primeros bytes de la api a nuestro buffer
mCopyMemory(miHookStruct->lpBuffer,miHookStruct->lpAPI,11);
//Cambiamos los la primera dirección que pushea 'Caller' por la un puntero a miHookStruct
mCopyMemory((LPSTR)Caller+1,(LPSTR)&miHookStruct,4);
//Cambiamos los la segunda dirección que pushea 'Caller' por la dirección de ControlFunction
LPSTR dirControlFunction=(LPSTR)ControlFunction;
mCopyMemory((LPSTR)Caller+6,(LPSTR)&dirControlFunction,4);
//Cambiamos los 10 primeros bytes de la API por la función Caller
mCopyMemory(miHookStruct->lpAPI,(LPSTR)Caller,11);
FlushInstructionCache(GetCurrentProcess(),0,0);
__asm popad;
}
//Función que simula RtlCopyMemory
void __declspec(naked) mCopyMemory(LPSTR bEscritura,LPSTR bLectura,DWORD lenBuffer)
{
__asm
{
pushad
mov esi,[esp+0x28] //bLectura
mov ecx,[esp+0x2C] //lenBuffer
mov edi,[esp+0x24] //bEscritura
dec ecx
bCopyMemory:
dec ecx
movsb
cmp ecx,0
jge bCopyMemory
popad
ret
}
}
miByte=1; //<<<<------ Habrá que inicializara a 1 ese byte no? sino pasan cosas malas xD
//Obtenemos la longitud del nombre de la API
for(int i=0;miByte;i++)
{
szName=i;
LPSTR puntero=ExeBuffer+ITD->u1.Function+2;
puntero+=i;
ReadProcessMemory(hProcess,puntero,&miByte,1,0);
}