Log in

View Full Version : Api hooking


w_a_r_1
January 28th, 2011, 00:14
Hi,

I am trying to hook an api named SetBkColor of any application. The normal color is black, now i want to make an external application which will load the target via createprocess api call and later when the program call the setbkcolor api, it just replace that first push which decide the color of BG.


Anyone got nice paper over this technique? i would appreciate if some share.

I looked over google, there are methods of dll injection to load in target process and call the dll function.. but how to replace.parameter stuff, i cant find any usuful.

Thank you.

Indy
January 28th, 2011, 09:27
IDP(for Gdi32!pGdiSharedHandleTable) or patch.

BanMe
January 28th, 2011, 10:43
yes, nice riddled answer Indy..

But the answers he seeks are in front of his nose..

msdn SetBkColor
Code:

COLORREF SetBkColor(
__in HDC hdc,
__in COLORREF crColor
);


2 parameters so hard to understand..

in code it looks like

Code:

push crColor
push hdc
call SetBkColor


edit crColor...

aqrit
January 29th, 2011, 00:59
you can hook the Import Address Table of the .EXE GetModuleHandle(NULL);
or you can hook the Export Address Table of the .DLL GetModuleHandle("GDI32.DLL";

then just point it at your own function
Code:

COLORREF __stdcall xSetBkColor( HDC hdc, COLORREF crColor){
return SetBkColor(hdc, myNewColor);
}


if you can be more specific I'm sure someone will point you at a good tutorial (there are lots of them around)

blabberer
January 30th, 2011, 01:06
you mean some kind of loader ?

here is a mod of dettens old loader example in c

victim code creates a window and puts some text in blue background
Code:

#include <windows.h>

LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{

WNDCLASSEX WndCls;
static char szAppName[] = "TEST";
MSG Msg;

WndCls.cbSize = sizeof(WndCls);
WndCls.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
WndCls.lpfnWndProc = WindProcedure;
WndCls.cbClsExtra = 0;
WndCls.cbWndExtra = 0;
WndCls.hInstance = hInstance;
WndCls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndCls.hCursor = LoadCursor(NULL, IDC_ARROW);
WndCls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndCls.lpszMenuName = NULL;
WndCls.lpszClassName = szAppName;
WndCls.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
RegisterClassEx(&WndCls);

CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
szAppName,
"SetBkColorExample",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);

while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage( &Msg);
}

return (Msg.wParam);

}



LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg,WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT Ps;

switch(Msg)
{
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &Ps);
SetBkColor(hDC, RGB(0, 0, 255));
TextOut(hDC, 50, 42, "SetBkColor Example ", sizeof("SetBkColor Example");
EndPaint(hWnd, &Ps);
break;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return 0;
}


loader that modifies the background color to cyan

Code:


#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
char NotLoaded[] = {"It did not work :-("};
unsigned long NewOpcode = 0x00ffff00;
unsigned long byteswritten,uExitCode=0;
STARTUPINFO startup;
PROCESS_INFORMATION processinfo;


memset(&startup, 0, sizeof(startup));
memset(&processinfo, 0, sizeof(processinfo));
startup.cb = sizeof(startup);

if(CreateProcess("setbk.exe",
NULL,
NULL,
NULL,
FALSE,
CREATE_DEFAULT_ERROR_MODE,
NULL,
NULL,
&startup,
&processinfo) == FALSE)
{
MessageBoxA(NULL,NotLoaded,NULL,MB_OK|MB_ICONERROR);
return FALSE;
}
else
{
Sleep(5000);
SuspendThread(processinfo.hThread);
WriteProcessMemory( processinfo.hProcess,
(void *)0x401125,
&NewOpcode,
4,
&byteswritten);
ResumeThread(processinfo.hThread);
Sleep(5000);
TerminateProcess(processinfo.hProcess,uExitCode);
return TRUE;
}
ExitProcess(0);
}


compile and link in vc6 release with

Code:


del *.exe
cl setbk.c /I"c:\Program Files\Microsoft Visual Studio\VC98\Include" user32.lib gdi32.lib /nologo
cl loader.c /I"c:\Program Files\Microsoft Visual Studio\VC98\Include" user32.lib /nologo
del *.obj
pause


run the loader.exe minimize and maximize the window a few times to see effect

w_a_r_1
January 31st, 2011, 03:46
Thank you for the source friend. I will look over it.

The application is having watermark over it. The program is demo and there is no registration process. Applicaiton is fully working the only issue is the watermark. I looked over almost all api calls but i have no idea which api call i should hook to change the watermark. Anyone can give me some useful api calls which programmers commonly use to put watermark over video output?

deroko
January 31st, 2011, 08:41
Yo may want to look into hooks of BitBlt and StretchBlt, as they are used to copy one DC to another.

Example:
Code:

GetClientRect(hwnd, &rect);
hbmp = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(102));
hdc = BeginPaint(hwnd, &ps);

hdcMem = CreateCompatibleDC(NULL);
SelectObject(hdcMem, hbmp);

GetObject(hbmp, sizeof(bm), &bm);

StretchBlt(hdc, 0,0, rect.right, rect.bottom, hdcMem, 0,0, bm.bmWidth, bm.bmHeight, SRCCOPY);

DeleteDC(hdcMem);
DeleteObject(hbmp);
EndPaint(hwnd, &ps);


You might also want to take snapshots of DCs and save them to bmp so you can easily see which one you are looking for. Hope this helps.

aqrit
January 31st, 2011, 12:28
video players tend to use DirectShow, DirectDraw, Direct3D, OpenGL, SDL, or GDI

pHi1t3r
January 31st, 2011, 19:22
API hooking might be a bit of an overkill. A lot of times watermarking is done by loading up some kind of bitmask and then overlaying that to change the color or texture of the overlapping pixels. It might be easier to find the mask that it uses and then just null the structure out. I just figured I'd put in my 2 cents in case you want to avoid a loader.