News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

[Win32] Placing a codecave into a DLL

Started by SucodoJ, December 02, 2013, 01:59:17 AM

Previous topic - Next topic

SucodoJ

Hello, I want to enhance a very old win32 program whose source code got lost long ago. I searched and found an adequate place inside a DLL this program is using. What I wanted to do now is placing a codecave into there that basically just loads and executes a function placed inside another DLL I created before.

Here is the crux I am facing: My codecave is somewhere in the empty part of the .text section. But now I don't know either the DLL module's base address or the base address of kernel32.dll where I can find LoadLibraryW. My goal is doing something like this:


OriginalDLLSection:
...
; some DLL code, blabla

MOV EDX, 0xDEADBEEF ; some uncertain handle value from the DLL gets stored, I need that in my own DLL
JMP CodeCaveSection ; <---- replaced some old, unneeded opcode with that injection of my codecave
POP EDI ; first opcode after my codecave, let it have symbolic address <ReturnAddressToOriginalDLLCode> now

; some more code, blabla




...




; Later on, at the end of the .text section, my codecave:

my_dll DB "my_custom_module.dll"
my_func DB "my_function" ; void my_function(DWORD)

...

CodeCaveSection:
; prepare LoadLibrary
PUSH my_dll ; problem: In OllyDbg, I must know the address where the DLL filename string is stored.
CALL <kernel32.LoadLibraryA> ; problem: I don't know the base address of kernel32 either
CMP EAX, 0 ; if loading failed...
JNZ <ReturnAddressToOriginalDLLCode> ; same problem as in push
PUSH EAX ; push the module handle
PUSH my_func
CALL <kernel32.GetProcAddressA>
CMP EAX, 0 ; function not found...
JNZ <ReturnAddressToOriginalDLLCode> ; back to original code, do nothin
PUSH EDX ; push the 0xDEADBEEF from above as the function argument of my_function
CALL EAX ; call my DLL function
JMP <ReturnAddressToOriginalDLLCode>


What I thought of was getting the return address of the original function from the stack and perform an AND with FFFF0000 to get the base address and add relative offsets (which I can read out of my debugger), so I can at least address my strings inside the codecave. But what about LoadLibrary and GetProcAddress? I heard I could find the base address of kernel32.dll inside the Import Address Table, but no idea how.

Sorry if my questions sound kind of dumb, I am not very into such low-level issues. I hope you understand my problem.

SucodoJ

Gunther

SucodoJ,

did you read the forum rules, especially rule #3? If not, you should do it immediately. What is a codecave? An unused block of memory that someone, typically a software cracker, can use to inject custom programming code to modify the behavior of a program.

Gunther

You have to know the facts before you can distort them.

SucodoJ

I haven't since the rules are the same everywhere anyway. Now I am just confirmed.
No need to tell me; I know what a codecave is.
I said it's about a piece of very old software that is neither sold or even published, it has been only developed for one purpose and it's about me to either enhance it with some features or abandon it completely which we really wouldn't like to do.

dedndave

no need to re-write the entire program
just re-write the DLL from scratch and modify the source code to suit your needs

we're not allowed to help people reverse-engineer code

Gunther

Dave,

thank you. You've underlined my point.  :t

Gunther
You have to know the facts before you can distort them.

fearless

Microsoft has a library that may be of use to you. Detours (http://research.microsoft.com/en-us/projects/detours/) which will eliminate the need for code caves. I have seen its use in the baldurs gate series of games - the Throne of Bhaal Extender project (ToBEx) uses this (http://www.shsforums.net/forum/606-tobex/) which allows for overriding hard coded limitations of the game engine and fixes bugs and other issues. The detours allows you to override an old function and 'trampoline' to a new function without the need for the codecave method. So might be worth a looksee. Hopefully that may help you.

Magnum

And code caves are a pain in the "Hintern".  :t

Andy
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

jj2007

Another option is to create a new DLL that 'passes on' some functions but fakes others. Here is an example that uses one CRT function and fakes a second one (always assuming that your fairy tale about old code and lost sources is correct ;)):
include masm32rt_nocrt.inc

.data?
hMs dd ? ; handle for MSVCRT dll
pPrint dd ? ; address of printf

.data
tx1 db "msvcrt.dll", 0
tx2 db "printf", 0

.code
LibMain proc instance:DWORD, reason:DWORD, unused:DWORD
  .if reason==DLL_PROCESS_ATTACH
invoke LoadLibrary, offset tx1 ; chr$("msvcrt.dll")
mov hMs, eax
invoke GetProcAddress, hMs, offset tx2 ; "printf"
mov pPrint, eax
  .elseif reason==DLL_PROCESS_DETACH
invoke FreeLibrary, hMs
  .endif
  mov eax, TRUE
  ret
LibMain endp

printf proc C args:VARARG ; $export
  push [ebp+16] ; ####### caution - this fake printf expects always three args,
  push [ebp+12] ; i.e. format, one string, one integer ##########
  push [ebp+8]
  call pPrint ; this calls the 'real' CRT printf
  add esp, 3*DWORD
  ret
printf endp

strlen proc pStr ; $export
  mov eax, pStr
  dec eax
  .Repeat ; slow but for a demo it's OK
inc eax
  .Until !byte ptr [eax]
  sub eax, pStr
  add eax, 1000 ; just to demonstrate that it's not the real CRT strlen
  ret
strlen endp
end LibMain