Jump to content
Tuts 4 You

Kol dll with MCK form


Recommended Posts

is anyone familiar with kol?

basically im try to inject a dll & show the form, but ive no idea what im doing with it (only just started using it)

This a VCL version that works but i cant seem to figure out how to do it with KOL.

why dont i just use the vcl version, because 1.xx mb is a joke & the VCL bloat gets bigger with every new release, hence the KOL replacement.






Source in 'Trainer.pas' {Form1};

{$R *.res}

procedure CreateForm;


Application.ShowMainForm := True;

with TForm1.Create(Application) do



procedure DllMain(Reason: DWORD);




if (Reason = DLL_PROCESS_ATTACH) then

    CreateThread(nil, 0, @CreateForm, nil, 0, a);

if (Reason = DLL_PROCESS_DETACH) then




DllProc := @DllMain;



you dont have to convert that, ill accept anything that works if it means not having to use a massive dll.


Edited by s0me0ne
Link to comment

Personally i wouldn't be creating a thread in DllMain, regardless of whether or not people say it isn't prone to deadlock issues.

Instead of doing this in dll main, i'd have a function exported from the dll which performs initialization or window/form creation. This could be called from the same thread which loads the library and when the window/form closes the thread can exit after calling FreeLibrary, it just means the CreateRemoteThread(LoadLibraryA) method is not suited to it.

PUSH XXXXXXXX <- offset of library name
CALL DWORD PTR [XXXXXXXX] <- DWORD variable which holds address of LoadLibraryA
PUSH EAX <- Push as parameter for call to FreeLibraryPUSH 1
CALL DWORD PTR [XXXXXXXX] <- DWORD variable which holds address of GetProcAddressCALL EAX <- Call function to create window, etcCALL DWORD PTR [XXXXXXXX] <- DWORD variable which holds address of FreeLibrary, hModule is already pushedPUSH 0
CALL DWORD PTR [XXXXXXXX] <- DWORD variable which holds address of ExitThread

As always, there are many spins on this. You can remove any need for the dword variables if you want to calculate the distance for each call to reach its respective API, but there is still a need to allocate memory to place the dll name into the remote process and Windows allocates a minimum of a page (1000h or 4096d bytes) so there is not any space being saved by not writing it there.

You can also simply use a RET to get back to where the thread function body was called from, it *should* eventually go back to ExitThread itself but it is not a bad habit to ensure your thread is dead when you've finished with it by calling ExitThread yourself.



EDIT: I've thrown together an offset independant version of what i described above to illustrate what i mean, if there are any code errors i apologize because i have not tested it, as i said it is more for theory than anything.

;// Get our delta address to base everything off,
;// trash EBP cos we are not worried about the ABI for the main body
call GetDelta
pop ebp;// Load the dll
lea ecx, dword ptr [ebp + (LibName_ - GetDelta)]
push ecx
call dword ptr [ebp + (LoadLibary_ - GetDelta)];// Push hModule for FreeLibrary call
push eax;// Push hModule for dll initialization function call
push eax;// Get the address of the initialization function,
;// ive used #1 as ordinal but you can use string if you want
push 1
push eax
call dword ptr [ebp + (GetProcAddress_ - GetDelta)];// hModule is already pushed to stack, initialization function is __stdcall so
;// it corrects the stack before returning to the caller
call eax;// Save return value to EBX for ExitThread, not following ABI still in main body
mov ebx, eax;// hModule is already pushed to stack, FreeLibrary function is __stdcall so
;// it corrects the stack before returning to the caller
call dword ptr [ebp + (FreeLibrary_ - GetDelta)];// Push return value as dwExitCode parameter to ExitThread IF DESIRED,
;// this is not necessary and can be omitted along with saving the value to EBX
push ebx
call dword ptr [ebp + (ExitThread_ - GetDelta)];// Begin data
ExitThread_ dd ?
GetProcAddress_ dd ?
FreeLibrary_ dd ?
LoadLibary_ dd ?
LibName_ db "SomeDll.dll",0
Edited by ghandi
Link to comment

as much as i appreciate the response, i really didnt get that.

anyway ive sort of got it working with remotethread.

probably not the best way to do it but it might help someone else at some point.

{ KOL MCK } // Do not remove this line!
library KOLdllForm;
unit1 in 'unit1.pas' {Form1};
//{$R *.res}
//{$R KOLdllForm.res}
//{$R WinXP.res}
Procedure RunKOLFormTest();
if not Assigned(Form1) then
NewForm1(Form1, nil);
ThreadID:cardinal;begin // PROGRAM START HERE -- Please do not remove this comment
{$IF Defined(KOL_MCK)} {$I KOLdllTest_0.inc} {$ELSE}
Application.CreateForm(TForm1, Form1);
{$IFEND} CreateThread(nil, 0, @RunKOLFormTest, nil, 0, ThreadID); // Working as intended //RunKOLFormTest; // Shows the Form but i have to close it before the main app will show (which defeats the purpose)

....where are the code tags?

nvm NoScripts doing it job

KOL-MCK dll 47.5KB vs XE2 VCL dll 6.77 MB (seriously, is there any need?)

Edited by s0me0ne
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...