Heya all..
here's a source for a harmless little hack I'm trying to get working, I intend to use it as part of a security scheme for my game engine.. can anyone see what I'm doing wrong here?

.586

.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

return macro pp:REQ
mov eax,pp
ret
endm
;==========================================================
.data
szFunc db "MessageBoxA",0
LibName db "USER32.DLL",0
szHeh db "Everybody was Kung-Fu Fighting", 0
IDTADDR db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

;==========================================================
.data?
hInstance dd ?
HackLib dd ?
HackProc dd ?
AddressToHack dd ?
ValToWrite dd ?
nextsehptr dd ?
origsehptr dd ?
seherrhandler dd ?
exception dd ?
oldoffset dd ?
ValueToWrite dd ?
;==========================================================
.code
;This is our fake function code, the example given below will alter
;the title of a message box which has been called with MessageBoxA
FakeFunc:
push ebp ; procedure prelude: save old base ptr
mov ebp, esp ; and create new stack frame
push 0 ; place a null byte onto stack
lea eax, szHeh ; eax = address of new title string
push dword ptr[ebp-20]
push eax ; push address of new title string
push dword ptr[ebp-12]
push dword ptr[ebp-8]
call MessageBoxA; call MessageBoxA
pop ebp ; get old stack base
ret 16 ; return to caller

;==========================================================
;This proc allocates a wad of globally accessible memory and copies the hook code into it
PlantFakeFunc proc FakeFuncBase:DWORD
LOCAL FakeFuncSize:DWORD
lea eax,szHeh ; Calculate the size of our fake function
lea ebx, FakeFunc
sub eax, ebx
mov FakeFuncSize, eax
; Allocate the required memory for it in shared memory so all processes can access it
; Replace the real
invoke VirtualAlloc, FakeFuncBase, FakeFuncSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
mov FakeFuncBase,eax
.if eax == NULL
return FALSE
.endif
; Copy the fake function into newly allocated shared memory
invoke RtlMoveMemory,FakeFuncBase, addr FakeFunc, FakeFuncSize
return TRUE
PlantFakeFunc ENDP
;===================================================================
;This procedure attempts to find the address of a function in the Export Table of a loaded DLL image.
;It returns the address of the function in memory.
FindRealProcAddy proc pTargetLib:PTR BYTE,pTargetApi:PTR BYTE
LOCAL baseAddress:DWORD
LOCAL fred:ptr DWORD
LOCAL tom:PTR DWORD
LOCAL bob:PTR WORD
LOCAL pIED:PTR IMAGE_EXPORT_DIRECTORY

mov fred,0
;Get the base address of our target library as it appears in virtual memory
invoke GetModuleHandle, pTargetLib
mov baseAddress ,eax
.if baseAddress == NULL
jmp quit
.endif
;Simply go through the PE header and get addr of Export Address Table...
mov eax, baseAddress ; move imagebase into eax
cmp word ptr[eax], 'ZM' ; check if we have a exe image
jne quit ; exit if we dont
add eax, 3Ch ; eax = pointer to pe header offset
mov ebx, [eax] ; get the pointer
add ebx, baseAddress ; add to image base to align it
cmp word ptr[ebx], 'EP' ; check if we have a pe image
jne quit ; exit if we dont
add ebx, 78h ; eax = pointer to virtual address of export dir address
mov ecx, [ebx] ; ecx = virtual address of export dir address
add ecx, baseAddress ; add imagebase to ecx to align
mov pIED, ecx

;This code will scan through the export table and find the VirtualAddress
;of our targt func and then return its addr in mem
xor ecx,ecx
mov ebx,pIED
.while ecx<[ebx].IMAGE_EXPORT_DIRECTORY.NumberOfFunctions
push ecx
shl ecx,2
add ecx,baseAddress
mov ebx,pIED
add ecx,[ebx].IMAGE_EXPORT_DIRECTORY.AddressOfNames
mov tom , ecx
add ecx,baseAddress
invoke lstrcmp,ecx, pTargetApi
.if eax==0
pop ecx
push ecx
shl ecx,1
add ecx,baseAddress
mov ebx,pIED
add ecx,[ebx].IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals
mov bob,ecx
pop ecx
shl ecx,2
add ecx,baseAddress
add ecx,[ebx].IMAGE_EXPORT_DIRECTORY.AddressOfFunctions
mov fred,ecx
jmp quit
.endif
pop ecx
inc ecx
mov ebx,pIED
.endw
quit: return fred
FindRealProcAddy endp
;=========================================================================
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke LoadLibrary,addr LibName
mov HackLib,eax ;Returns the Base Address of the DLL
invoke GetProcAddress, HackLib,addr szFunc
mov HackProc,eax ;Returns the Virtual Address of the Function
invoke FindRealProcAddy,HackLib,HackProc
mov AddressToHack,eax ;Returns the REAL Address of the Function
lea eax,FakeFunc ;Point to start of Hook
sub eax, hInstance ;Subtract THIS IMAGE Base Address
mov ValToWrite,eax ;Remember the offset of the Hook code
invoke PlantFakeFunc,addr FakeFunc

;Hacking Original SEH pointer...
assume fs:nothing
;PUSH FS:[0]

mov eax, fs:[0]
mov nextsehptr, eax; set in structure
mov origsehptr, eax ; save it
lea eax, return_to_host ; change it to our code
mov seherrhandler, eax ; ...
mov eax, nextsehptr ; ...
mov fs:[0],eax ; replace the structure

;Hacking Interupt Discriptor Table...
sidt IDTADDR ; get interrupt discriptor table addr
lea esi,IDTADDR
lea esi, dword ptr [esi+2] ; first 2 bytes are the length
add esi, 4*8 ; get the offset for our int 4
mov exception,esi ; save exception place
mov bx, word ptr [esi+6] ; get the low word
shl ebx, 10h ; shift it left
mov bx, word ptr [esi] ; and get the high word
mov dword ptr [oldoffset], ebx ; save exception offset
lea eax, Ring0 ; eax is our new software interupt func
mov word ptr [esi], ax ; store the high word
shr eax, 10h ; shift it right
mov word ptr [esi+6], ax ; and store the low word

;this means that when we do int 4 we will go to our code (at ring0) ;)
;Going Into Ring0...
mov eax, AddressToHack ; eax = the address which holds the va of the exported func
mov ebx, ValueToWrite ;ebx = the address we wish to change it to so it points to our FakeFunc
int 4 ; generate the interupt so we drop to Ring0

;Restoring Original IDT And SEH Pointer... ;)
mov esi, exception ; restore the IDT address
mov ebx, oldoffset ; restore exception offset
mov word ptr [esi], bx ; restore the exception
shr ebx, 10h ; shift it left
mov word ptr [esi+6], bx ; put it back
return_to_host:
mov eax, origsehptr ; eax = the old SEH pointer
mov fs:[0],eax ; restore it
die: invoke ExitProcess,0
return 0

;==========================================================
Ring0: ; THIS CODE EXECUTES AT RING0
; EAX = Address To Write To
; EBX = Value To Write
mov dword ptr[eax], ebx ; change the export address
iretd ; return to Ring3

;==========================================================
end start
Posted on 2004-01-01 11:17:20 by Homer
Hrm... haven't looked to much at your code, but there seems to be a couple of problems from reading the comments:

"Allocate the required memory for it in shared memory so all processes can access it" - there's no such thing on win32. It's sorta available on 9x, but definitely not NT.

Hacking the IDT is a bad bad bad idea - and you should only be able to get away with it under 9x. On NT, it will be considered a security break, and if you can get away with it, it will be fixed in a service pack.

If you really need ring0 for some silly 'security', do it like the 'respectable' companies do it - VXD/KMD. And good luck finding a generic win32 method of allocating global shared memory ;)
Posted on 2004-01-01 15:09:50 by f0dder

it will be fixed in a service pack.

Are you sure? (I think they'll just relocate it, you know it's probably a feature (a design choise, you know ActiveX can more more than java because it's not in a sandbox, right?))

If you're up for playing with the IDT, why make your own OS ;)
Posted on 2004-01-01 15:41:12 by scientica

If you're up for playing with the IDT, why make your own OS ;)
Hardware drivers come to mind - these companies are running a racket, scratching each others backs while sleeping in the same bed. :) EvilHomer2k, should just sit back and wait for DRM to take hold then use the API. :(
Posted on 2004-01-01 15:50:33 by bitRAKE
I'll try implanting it in a DLL, that should make it globally accessible under NT as well, right? ;) All I'm trying to do is find a way to generically hook a known function in a DLL which is already loaded.. without using the hook api.
Posted on 2004-01-01 23:20:50 by Homer
Homer,
Some errors I noticed


FakeFunc:
push ebp ; procedure prelude: save old base ptr
mov ebp, esp ; and create new stack frame
push 0 ; place a null byte onto stack
lea eax, szHeh ; eax = address of new title string
push dword ptr[ebp-20]
push eax ; push address of new title string
push dword ptr[ebp-12]
push dword ptr[ebp-8]
call MessageBoxA; call MessageBoxA
pop ebp ; get old stack base
ret 16 ; return to caller

should be


FakeFunc:
push ebp ; procedure prelude: save old base ptr
mov ebp, esp ; and create new stack frame
push 0 ; place a null byte onto stack
lea eax, szHeh ; eax = address of new title string
push dword ptr[ebp+20]
push eax ; push address of new title string
push dword ptr[ebp+12]
push dword ptr[ebp+8]
call MessageBoxA; call MessageBoxA
pop ebp ; get old stack base
ret 16 ; return to caller

Also your code will break at "mov bx, word ptr " with the error memory not accessible or something like on nt if I am not wrong... Since your main aim is to break into ring0 from ring3 by editing the interrupt table, I would suggest you take a look at the following: http://www.asmcommunity.net/board/index.php?topic=15001
Posted on 2004-01-02 05:52:14 by roticv
Wow, I'm impressed you remember that thread :)
I just want to add some precisions. The method in that thread doesn't edit the IDT, but the GDT, though it could easily be modified to edit the IDT. And be careful with the source in that thread, it is full of bugs and very very unstable...
Posted on 2004-01-02 14:03:28 by Chrishka

I'll try implanting it in a DLL, that should make it globally accessible under NT as well, right?

Nope, DLLs are loaded per-process - as they should be.


All I'm trying to do is find a way to generically hook a known function in a DLL which is already loaded.. without using the hook api.

This takes quite some work - you're trying to do a global API hook, right? It's not too bad on 9x afaik, but on NT... argh. Take a look at the microsoft detours project, and read the docs - it outlines some of the problems etc.
Posted on 2004-01-02 14:16:42 by f0dder