Flag: Tornado! Hurricane!

Blogs >> anonymouse's Blog

Created: Friday, June 30 2006 14:15.10 CDT Modified: Wednesday, July 12 2006 11:18.49 CDT
Printer Friendly ...
added one more command Loaddll to my modified commandline plugin
Author: anonymouse # Views: 3049

i have added one more command loaddll to my modified commandline plugin

this was kind of bitch to do

i was thinking of allocating a space in child (debuggee)
and then just insert a LoadLibraryA() and jump back

but in practice this turned out to be more problamatic than one could imagine killing all the bugs that were popping up
was a real nice learning experience

first i though ollydbg's Go function will execute and return control after execution
but that was wrong assumption no 1 :)
it just queed it up in some place and returned immediately
and i thinking all is great and well
asked ollydbg to VirtualFree and return

bingo ollydbg now looks for the unavailable memory
trying to execute code in thin air

ok i comment out the virtualfree and insert shellcode
like LoadLibrary() push params and jmp VirtualFree

it was kinda working in 9x (due to shared memory)
but in NT the Hdebugee that i passed was going crazy
ok ill thought hardcode GetCurrentProcess() result
since i was interested in killing myself
so goes out hDebugee and enters 0xffffffff
ok it works in both os

but now i have no way to restore the earlier registers
because i killed myself and the registers had the result of
VirtualFree

and there was one more quirk in win9x if i call the Function Directly it just doesnt restore the stack
i have to pass through a constant hoop address
thats hardcoded in 9x kernel 0xbff9 only if run through this hoop the stack status was restored
and no where i can find info on what the constant address was and if there is a way to get it programtically

some thunk to some place its called it seems

ok this was turning out to be a hack job instead of a clean work

also without having the registers restored it was anyway going to crash and burn some place down
though it worked statically

i discarded this approach
and thought ill add a pausedEx handler
because ollydbgs Go was setting a tempbreakpoint on the
return address i thought ill catch it and free

now enters ollydbg tempbreakpoint quirks
in 9x it uses int3 and in > nt it uses hardware bp

now i was just catching EXCEPTION_BREAK_POINT
and nt hbp creates EXCEPTION_SINGLE_STEP :)

one more hoop

i start checking for both
and it seemed to work properly was loading and freeing memory as long as i was doing it in user code eip

i run hit pause and then loaddll
and it crashes in nt :)

and to identify why the heck it is crashing took another round of googling
the eip when process was suspended turns out to be
KiFastSystemCallRet

and that eip is being executed 1000s of time
by any function that enters system via sysenter
LoadLibrary definately enters system multiple times
before returning to the return address :)
and my handler was freeing memory just at the first hit
and voila it returns to nonexistent memory
and crashes

finally after all this i added a few more
if but then else GO()

and it seems to be working well now

i havent tested  this in a system that uses int2e

my xp-sp2 and win9x tests both work smoothly

if some one finds any problems in int2e systems please
message me back


i am pasting my code below look at my earlier blog
on using this code

as usual ill mail pedram with source and precompiled plugin
till then any criticisms bug reports flames are welcome



/* modfied command line plugin
command added Loaddll
usage
replace the default cmdline plugin with new one
alt+f1
type Loaddll "yourdll"
if successfully loaded you can see a log entry "loaded "your dll"" in ollydbg log window
and you can see your dll in memory window
modified by anonymouse
*/




#define MEM_SHARED 0x8000000 // thanks ElicZ for this 9x hack
#define STRICT                       // Avoids some type mismatches
#include <windows.h>
#include <stdio.h>
#include "plugin.h"

int magic(void);
extern char string[TEXTLEN];// defined in cmdexec.c
char copy[TEXTLEN];
ulong eip;
ulong esp;
ulong status;
HANDLE hDebugee;
char *hMem;

int magic()
{
t_thread *thread;
t_asmmodel model;
char buffer[TEXTLEN] = {0};
char error[TEXTLEN] = {0};
int len,totallen;
strncpy(copy,string,(TEXTLEN-1));
hDebugee  = (HANDLE)Plugingetvalue(VAL_HPROCESS);
thread   = Findthread(Getcputhreadid());
eip   = thread->reg.ip;
esp   = thread->reg.r[REG_ESP];
totallen = 0;

if(GetVersion() > 0x80000000)
{
hMem = (CHAR *)VirtualAlloc(NULL,1000,MEM_COMMIT|MEM_RESERVE|MEM_SHARED,PAGE_EXECUTE_READWRITE);
}
else
{
hMem = (CHAR *)VirtualAllocEx(hDebugee,NULL,1000,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
}

WriteProcessMemory(hDebugee, (LPVOID)(hMem), copy, strlen(copy), 0);

snprintf(buffer,(TEXTLEN-1),"%s","pushad");
len = Assemble(buffer, (ULONG_PTR)(hMem+500 + totallen), &model, 0, 0, error);
WriteProcessMemory(hDebugee, (LPVOID)(hMem+500 + totallen), model.code, len, 0);
totallen += len;

snprintf(buffer,(TEXTLEN-1),"%s","pushfd");
len = Assemble(buffer, (ULONG_PTR)(hMem+500 + totallen), &model, 0, 0, error);
WriteProcessMemory(hDebugee, (LPVOID)(hMem+500 + totallen), model.code, len, 0);
totallen += len;

snprintf(buffer,(TEXTLEN-1),"push 0x%lx",*(ulong *)&hMem);
len = Assemble(buffer, (ULONG_PTR)(hMem+500 + totallen), &model, 0, 0, error);
WriteProcessMemory(hDebugee, (LPVOID)(hMem+500 + totallen), model.code, len, 0);
totallen += len;

snprintf(buffer,(TEXTLEN-1),"call %s","LoadLibraryA");
len = Assemble(buffer, (ULONG_PTR)(hMem+500 + totallen), &model, 0, 0, error);
WriteProcessMemory(hDebugee, (LPVOID)(hMem+500 + totallen), model.code, len, 0);
totallen += len;


snprintf(buffer,(TEXTLEN-1),"%s","popfd");
len = Assemble(buffer, (ULONG_PTR)(hMem+500 + totallen), &model, 0, 0, error);
WriteProcessMemory(hDebugee, (LPVOID)(hMem+500 + totallen), model.code, len, 0);
totallen += len;

snprintf(buffer,(TEXTLEN-1),"%s","popad");
len = Assemble(buffer, (ULONG_PTR)(hMem+500 + totallen), &model, 0, 0, error);
WriteProcessMemory(hDebugee, (LPVOID)(hMem+500 + totallen), model.code, len, 0);
totallen += len;

snprintf(buffer,(TEXTLEN-1),"jmp 0x%lx",eip);
len = Assemble(buffer, (ULONG_PTR)(hMem+500 + totallen), &model, 0, 0, error);
WriteProcessMemory(hDebugee, (LPVOID)(hMem+500 + totallen), model.code, len, 0);

thread->reg.ip = (ULONG_PTR)hMem+500;
thread->reg.modified = 1;
thread->regvalid = 1;
Broadcast(WM_USER_CHREG, 0, 0);
Go(Getcputhreadid(), eip, STEP_RUN, 0, 1);
return 0;
}


int Load(char *answer,ulong parm)
{


if(Getstatus() == STAT_NONE)
{
MessageBox(NULL,"I Cant Load Dlls On Thin Air Start Some Process First","LoadDll Function",NULL);
return 0;
}
else if(Getstatus() == STAT_RUNNING)
{
status = 1;
Suspendprocess(1);
magic();
return 0;
}
else if(Getstatus() == STAT_STOPPED)
{
status = -1;
magic();
return 0;

}
else
{
return 0;
}

}



#pragma argsused
extc int _export cdecl ODBG_Pausedex(int reason, int extdata, t_reg *reg, DEBUG_EVENT *debugevent)
{
DWORD Exceptcode;
DEBUG_EVENT debev;
ulong newesp;
t_thread *newthread;



if (reg != 0)
{
if(debugevent !=0)
{

debev = *debugevent;
Exceptcode = debev.u.Exception.ExceptionRecord.ExceptionCode;

if((Exceptcode != EXCEPTION_BREAKPOINT) && (Exceptcode != EXCEPTION_SINGLE_STEP))
{
return 0;
}


if (debev.u.Exception.ExceptionRecord.ExceptionAddress == (PVOID)(eip))
{
if(GetVersion() > 0x80000000)
{
Addtolist(0,1,"Loaded %s ",copy);
VirtualFree(hMem,0,MEM_RELEASE);
if(status == 1)
Go(Getcputhreadid(), 0, STEP_RUN, 0, 1);
eip = esp = status = *copy = 0;
return 0;
}
else
{

newthread  = Findthread(Getcputhreadid());
newesp   = newthread->reg.r[REG_ESP];
if(esp == newesp)
{
Addtolist(0,1,"Loaded %s ",copy);
VirtualFreeEx(hDebugee,hMem,0,MEM_RELEASE);
if(status == 1)
Go(Getcputhreadid(), 0, STEP_RUN, 0, 1);
eip = esp = status = *copy = 0;
return 0;
}
Go(Getcputhreadid(), eip, STEP_RUN, 0, 1);
return 0;
}
}
}

}
return 0;
};







thanks to BillyBoBob who initially asked for this functionality in #openrce and who took some pains to
check all of my buggy prealpha prebeta alpha beta releases
thanks to Alex too for confirming that process handles
are perprocess and i cant embed a handle from remote process to kill myself i have to do GetCurrentprocess()
and pass that value also thanks for pointing out some funky casting problems which i hope i corrected :) and thanks to Zairon for checking this on xp-sp1
the code pasted wasnt updated one so updated it today

pedram has uploaded the new package to downloads section today
[url] https://www.openrce.org/downloads/details/206/Modified%20CmdLine%20Plug-in [/url]









Add New Comment
Comment:









There are 31,316 total registered users.


Recently Created Topics
[help] Unpacking VMP...
Mar/12
Reverse Engineering ...
Jul/06
hi!
Jul/01
let 'IDAPython' impo...
Sep/24
set 'IDAPython' as t...
Sep/24
GuessType return une...
Sep/20
About retrieving the...
Sep/07
How to find specific...
Aug/15
How to get data depe...
Jul/07
Identify RVA data in...
May/06


Recent Forum Posts
Finding the procedur...
rolEYder
Question about debbu...
rolEYder
Identify RVA data in...
sohlow
let 'IDAPython' impo...
sohlow
How to find specific...
hackgreti
Problem with ollydbg
sh3dow
How can I write olly...
sh3dow
New LoadMAP plugin v...
mefisto...
Intel pin in loaded ...
djnemo
OOP_RE tool available?
Bl4ckm4n


Recent Blog Entries
halsten
Mar/14
Breaking IonCUBE VM

oleavr
Oct/24
Anatomy of a code tracer

hasherezade
Sep/24
IAT Patcher - new tool for ...

oleavr
Aug/27
CryptoShark: code tracer ba...

oleavr
Jun/25
Build a debugger in 5 minutes

More ...


Recent Blog Comments
nieo on:
Mar/22
IAT Patcher - new tool for ...

djnemo on:
Nov/17
Kernel debugger vs user mod...

acel on:
Nov/14
Kernel debugger vs user mod...

pedram on:
Dec/21
frida.github.io: scriptable...

capadleman on:
Jun/19
Using NtCreateThreadEx for ...

More ...


Imagery
SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit