flat assembler
Message board for the users of flat assembler.

Index > Windows > Interesting Time Problem

Goto page 1, 2, 3  Next
Author
Thread Post new topic Reply to topic
r22



Joined: 27 Dec 2004
Posts: 805
r22
I have a SERVER where testing is done.

The SERVER is an IIS / asp.net webserver.

The asp.NET code uses *** DateTime.Now ***,
because of the nature of the code the time is an important part of testing.

Here's the problem...
To test with different times you'd just reset the time on the SERVER,
BUT YOU CAN'T because resetting the time kills it's connection to the DOMAIN (which is necessary).

The QUESTION...
How do I make ONLY .NET think the time is different ?????

Can I DLL Inject the w3wp.exe and/or aspnet_wp.exe processes and detour the GetSystemTime api? Does .NET even use GetSystemTime or does it calculate the time from another api?


I've already started on ASM code to inject the DLL, which seems to work, however API hooking isn't my forte.

Any help / input / ideas would be appreciated.

Inject
Code:
format PE CONSOLE
include 'win32ax.inc'

section '.text' code readable executable
start:
        cinvoke printf,<'Start',13,10,0>
;;;ITERATE
        invoke  EnumProcesses,processes,4096,bRet
        mov     ebx,dword[bRet]
        shr     ebx,2
        cinvoke printf,<'Enum # %d Processes',13,10,0>,ebx
        mov     esi,processes
        lea     edi,[esi+ebx*4]
.iter:
        ;;cinvoke printf,<'%d',9,0>,dword[esi]
        add     esi,4
        cmp     esi,edi
        jne     .iter
        cinvoke printf,<13,10,0>
;;;OPEN PROCESS
        mov     esi,processes
.open:
        invoke  OpenProcess,PROCESS_ALL_ACCESS,0,dword[esi]
        test    eax,eax
        jz      .skip
        mov     ebx,eax
        invoke  EnumProcessModules,ebx,hMod,4,bRet
        invoke  GetModuleBaseName,ebx,dword[hMod],sName,MAX_PATH
        invoke  lstrcmpi,sName,sTest1
        jz      .found
        invoke  lstrcmpi,sName,sTest2
        jz      .found
        jmp     .next
;;;ALLOCATE MEM
.found:
        cinvoke printf,<'NAME:',9,'%s',13,10,'PID:',9,'%d',13,10,'HANDLE:',9,'%d',13,10,0>,sName,dword[esi],ebx
        invoke  VirtualAllocEx,ebx,0,1024*1024,MEM_COMMIT,PAGE_EXECUTE_READWRITE
        test    eax,eax
        jz      .next
        mov     dword[pMem],eax
        cinvoke printf,<9,'Mem Alloc = %X',13,10,0>,dword[pMem]

        invoke  WriteProcessMemory,ebx,dword[pMem],sDLL,sDLL_size,bRet
        test    eax,eax
        jz      .fail
        cinvoke printf,<9,'Written:',9,'%d',13,10,0>,dword[bRet]
        invoke  GetModuleHandle,"kernel32.dll"
        invoke  GetProcAddress,eax,"LoadLibraryA"
        push    eax
        cinvoke printf,<9,'LoadLibraryA:',9,'%X',13,10,0>,eax
        pop     eax
        invoke  CreateRemoteThread,ebx, 0, 0,eax,dword[pMem],0,thrID
        test    eax,eax
        jz      .fail
        cinvoke printf,<9,'Thread:',9,'%d',13,10,0>,eax
        invoke  SleepEx,2000,0

.fail:
        invoke  VirtualFreeEx,ebx,dword[pMem],0,MEM_RELEASE
.next:
        invoke  CloseHandle,ebx
.skip:
        add     esi,4
        cmp     esi,edi
        jne     .open

        cinvoke system,"pause"
        invoke  ExitProcess,0

section '.data' data readable writeable

sDLL:           db 'c:\fasm\hook.dll',0
sDLL_size = $-sDLL
sTest1          db 'ASPNET_WP.EXE',0
sTest2          db 'W3WP.EXE',0
thrID           dd 0
pMem            dd 0
bRet            dd 0
hMod            dd 0
sName           rb MAX_PATH + 1
processes       rd 1024
                dd 0

section '.idata' import data readable writeable

        library kernel32,'KERNEL32.DLL',\
             user32,'USER32.DLL',\
             gdi32,'GDI32.DLL',\
             advapi32,'ADVAPI32.DLL',\
             msvcrt,'MSVCRT.DLL',\
             psapi,'PSAPI.DLL'

     include 'API/kernel32.inc'
     include 'API/user32.inc'
     include 'API/gdi32.inc'
     include 'API/advapi32.inc'

     import msvcrt,\
            system,'system',\
            printf,'printf'
     import psapi,\
            GetModuleBaseName,'GetModuleBaseNameA',\
            EnumProcesses,'EnumProcesses',\
            EnumProcessModules,'EnumProcessModules'
    


DLL
Code:
format PE GUI 4.0 DLL
entry DLLMain
include 'win32ax.inc'

section '.text' code readable executable

DLLMain:
        mov     eax,[esp+8];;;reason
        cmp     eax,DLL_PROCESS_DETACH
        je      .detach
        cmp     eax,DLL_PROCESS_ATTACH
        je      .attach
.finish:
        mov     eax,TRUE
        ret     12

.detach:
        jmp     .finish
;;;ATTCH HOOK
.attach:
;;;
        ;;;invoke  ExitProcess,0
        ;;invoke  MessageBox,0,"Hook","Success",0
        jmp     .finish


Complete:
        ret     4

;;;found on fasm board
KernelBase:
        mov     eax, [fs:30h]
        test    eax, eax
        js      .9x
        mov     eax, [eax+0ch]
        mov     eax, [eax+1ch]
        mov     eax, [eax]
        mov     eax, [eax+8]
        retn
.9x:
        mov     eax, [eax+34h]
        lea     eax, [eax+7ch]
        mov     eax, [eax+3ch]
        retn
;;;found on fasm board
GetAPI:
        push    ebp
        mov     ebp, esp
        ;stack
        ;ebp+0Ch        sz api
        ;ebp+08h        mod handle
        push    esi edi ebx
        mov     esi, [ebp+08h]
        cmp     word [esi], 'MZ'
        jnz     .err
        add     esi, [esi + 03ch]
        cmp     dword [esi], 'PE'
        jnz     .err
        mov     edi, [ebp+0Ch]
        mov     ecx, 200
        xor     al, al
        repnz   scasb
        mov     ecx, edi
        sub     ecx, [ebp+0Ch]
        mov     edx, [esi + 078h]
        add     edx, [ebp+08h]
        mov     ebx, [edx+20h]
        add     ebx, [ebp+08h]
        xor     eax, eax
      .l1:
        mov     edi, [ebx]
        add     edi, [ebp+08h]
        mov     esi, [ebp+0Ch]
        push    ecx
        repz    cmpsb
        jz      .l2
        pop     ecx
        add     ebx, 4
        inc     eax
        cmp     eax, [edx+18h]
        jz      .l3
        jmp     .l1
      .l2:
        add     esp, 4
      .l3:
        cmp     eax, [edx+18h]
        je      .err
        mov     esi, [edx+24h]
        add     esi, [ebp+08h]
        push    edx
        mov     ebx, 2
        xor     edx, edx
        mul     ebx
        pop     edx
        add     eax, esi
        xor     ecx, ecx
        mov     word cx, [eax]
        mov     edi, [edx+1Ch]
        xor     edx, edx
        mov     ebx, 4
        mov     eax, ecx
        mul     ebx
        add     eax, [ebp+08h]
        add     eax, edi
        mov     eax, [eax]
        add     eax, [ebp+08h]
        jmp     .ret
      .err:
        xor     eax, eax
      .ret:
        pop     ebx edi esi
        leave
        retn    2*04h

section '.data' data readable writeable

hMod    dd 0

section '.idata' import data readable writeable

        library kernel32,'KERNEL32.DLL',\
             user32,'USER32.DLL',\
             gdi32,'GDI32.DLL',\
             advapi32,'ADVAPI32.DLL'

     include 'API/kernel32.inc'
     include 'API/user32.inc'
     include 'API/gdi32.inc'
     include 'API/advapi32.inc'

section '.edata' export data readable

  export 'HOOK.DLL',\
         Complete,'Complete'

section '.reloc' fixups data discardable
    
Post 18 Jun 2009, 18:03
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
r22, if you already managed to get the DLL work into the foreign process then I suggest you NOT try to lookup GetSystemTime/whatever, just import it and let Windows fill the import table with the precious address for you.
Post 18 Jun 2009, 19:46
View user's profile Send private message Reply with quote
asmcoder



Joined: 02 Jun 2008
Posts: 784
asmcoder
[content deleted]


Last edited by asmcoder on 14 Aug 2009, 14:50; edited 1 time in total
Post 18 Jun 2009, 19:55
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22
@*
Another interesting note, according to the SDK documentation on CreateRemoteThread I shouldn't be able to create a remote thread in a process from another session/user (which the aspnet_wp and w3wp exe's are because they run under another account), but yet I'm able to. Possibly because I'm creating the thread at the address of LoadLibraryA.

@asmcoder
I'd have to do more research and actually decompile the EXE before I could try your suggestion (I didn't really want to go through the trouble of all of that), but it might be necessary.

@LocoDel
LocoDelAssembly wrote:
r22, if you already managed to get the DLL work into the foreign process then I suggest you NOT try to lookup GetSystemTime/whatever, just import it and let Windows fill the import table with the precious address for you.


So something like...
Code:
mov ebx,[GetSystemTime]
invoke VirtualProtect ??;;; add write access
mov byte[ebx],JUMP_OPCODE
mov dword[ebx+1],Patched_GetSystemTime
    
Post 18 Jun 2009, 20:46
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2466
Location: Bucharest, Romania
Borsuc
asmcoder wrote:
first of all you CANT hook anything on windows.
Yes you can. I use an app called JauntePE everyday (hooks Registry calls to redirect them so it makes the apps portable -- that is, without touching the system drive). I'm not sure how it does it though.

_________________
Previously known as The_Grey_Beast
Post 18 Jun 2009, 20:46
View user's profile Send private message Reply with quote
asmcoder



Joined: 02 Jun 2008
Posts: 784
asmcoder
[content deleted]


Last edited by asmcoder on 14 Aug 2009, 14:50; edited 1 time in total
Post 18 Jun 2009, 21:06
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2466
Location: Bucharest, Romania
Borsuc
asmcoder wrote:
no u cant! (ok maybe, i will look into debug apis).
What are we children arguing?
I gave you an example program, search for it. Or search for the "madhook" dll library (I think JauntePE is based on it).

If you're saying it does something else than hooking Windows APIs for a specific application, then tell me how it manages to hook the registry APIs and some special filesystem APIs (like the "Special Folders" you know, Application Data, My Documents, crap like that).

Don't tell me "no u cant" because I use it everyday.
Or at least tell me why what it does isn't 'hooking' by your definitions?

_________________
Previously known as The_Grey_Beast
Post 18 Jun 2009, 21:38
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Quote:

So something like...


Code:
proc hook_GetSystemTime uses ebx
local oldProtect: DWORD
      virtual
        jmp $-5
        load .jmp_op word from $$
      end virtual

      mov     ebx, [GetSystemTime]
      cmp     word [ebx], $FF8B ; "mov edi, edi" but not encoded as FASM do
      jne     .unhookable ; (Trivially)

      invoke  VirtualProtect, addr ebx-5, 7, PAGE_EXECUTE_READWRITE, addr oldProtect
      test    eax, eax
      jz      .protFail

      mov     byte [ebx-5], $E9
      mov     eax, hook
      sub     eax, ebx
      mov     [ebx-4], eax

      mov     word [ebx], .jmp_op

      invoke  VirtualProtect, addr ebx-5, 7, [oldProtect], addr oldProtect

      mov     eax, TRUE ; In case VirtualProtect failed

.return:
      ret

.unhookable:
.protFail:
      mov     eax, FALSE
      jmp     .return
endp    
Post 18 Jun 2009, 21:44
View user's profile Send private message Reply with quote
asmcoder



Joined: 02 Jun 2008
Posts: 784
asmcoder
[content deleted]


Last edited by asmcoder on 14 Aug 2009, 14:50; edited 1 time in total
Post 18 Jun 2009, 22:45
View user's profile Send private message Reply with quote
arigity



Joined: 22 Dec 2008
Posts: 45
arigity
http://flatassembler.net/examples/detour_example.zip fasm windows hooking example....

also, theres an API for it (SetWindowsHook)
Post 18 Jun 2009, 22:47
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22
The exciting conclusion tomorrow (time pending) I give it a test.

-I'll patch GetSystemTime and GetLocalTime
-Have them return some hard coded time (if all goes well I'll have the dll read the time I'd like from a file that can be edited easily)
-Make an asp.net page that just displays DateTime.Now.ToString()
-See if the hack overrides it or not.

Should be ifun.
Post 18 Jun 2009, 23:04
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
r22, I've just coded a C# program and debugged under OllyDbg. I've set breakpoints on the APIs you mention but nothing happened. The one that was caught by a breakpoint was GetSystemTimeAsFileTime.

The code:
Code:
using System;

namespace TestsPad
{
    class Program
    {
        static void Main(string[] args)
        {
            for (; ; )
            {
                Console.WriteLine(DateTime.Now.ToString());
                System.Threading.Thread.Sleep(1000);
            }                
        }
    }
}    


OllyDbg was interrupting the execution of the program above every second after the breakpoint was set.
Post 18 Jun 2009, 23:24
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
r22
It works! (using GetSystemTimeAsFileTime).

I've done it locally using the aspnet_wp exe, once I get it to a more generic/customizable implementation I'll test on a server which uses w3wp.exe instead.

For completeness here's the updated DLL code.
Code:
format PE GUI 4.0 DLL
entry DLLMain
include 'win32ax.inc'

section '.text' code readable executable

DLLMain:
        push    ebp
        mov     ebp,esp
        push    ebx esi edi
        mov     eax,[ebp+12];;;reason
        cmp     eax,DLL_PROCESS_DETACH
        je      .detach
        cmp     eax,DLL_PROCESS_ATTACH
        je      .attach
.finish:
        invoke  CreateFile,<'c:/usertest/return.txt',0>,GENERIC_READ + GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
        invoke  CloseHandle,eax
        mov     eax,TRUE
        pop     edi esi ebx
        mov     esp,ebp
        pop     ebp
        ret     12
.detach:
        invoke  CreateFile,<'c:/usertest/detached.txt',0>,GENERIC_READ + GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
        invoke  CloseHandle,eax
        jmp     .finish
;;;ATTCH HOOK
.jmp_op:         jmp $-5
.attach:
        mov     ebx,[GetSystemTimeAsFileTime]
        lea     esi,[ebx-5]
        cmp     word [ebx], $FF8B ; "mov edi, edi" but not encoded as FASM do
        jne     .fail ; (Trivially)
        invoke  VirtualProtect,esi,7,PAGE_EXECUTE_READWRITE,oldProtect
        test    eax, eax
        jz      .fail
        mov     byte [ebx-5], $E9
        mov     eax,GetSystemTimeAsFileTime_patch
        sub     eax, ebx
        mov     [ebx-4], eax
        mov     di,word[.jmp_op]
        mov     word [ebx],di
        invoke  VirtualProtect,esi,7,[oldProtect],oldProtect
        test    eax, eax
        jz      .fail
        jmp     .finish
.fail:
        invoke  CreateFile,<'c:/usertest/fail.txt',0>,GENERIC_READ + GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
        invoke  CloseHandle,eax
        jmp     .finish

GetSystemTimeAsFileTime_patch:
        mov     eax,[esp+4]
        mov     dword[eax],555555
        mov     dword[eax+4],555555
        ret     4

Complete:
        ret     4

section '.data' data readable writeable

oldProtect      dd 0

section '.idata' import data readable writeable

        library kernel32,'KERNEL32.DLL',\
             user32,'USER32.DLL',\
             gdi32,'GDI32.DLL',\
             advapi32,'ADVAPI32.DLL'

     include 'API/kernel32.inc'
     include 'API/user32.inc'
     include 'API/gdi32.inc'
     include 'API/advapi32.inc'

section '.edata' export data readable

  export 'HOOK.DLL',\
         Complete,'Complete'

section '.reloc' fixups data discardable
    

For those curious the time displayed with the above is 7/24/1608 12:17:35 PM

I appreciate all the help, especially LocoDel actually researching the correct API for me (I was just guessing Very Happy).

This should make testing and QA much more efficient.

This would be a good addition for the examples section...
Post 19 Jun 2009, 14:44
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Just some minor "corrections":
* "jne .fail ; (Trivially)" should be changed to "jne .fail" (the comment made sense with the .unhookable label but now not Razz).

* Why haven't you used the virtual block this time? It makes both the source and executable smaller.


asmcoder, I believe you think this way of hooking can't work at times due to multi-tasking? Could you comment the particular scenario it will fail? (Besides that only one hook over the same API will be available rather than a chain of several hooks but without crashing the app in any moment).
Post 19 Jun 2009, 15:19
View user's profile Send private message Reply with quote
asmcoder



Joined: 02 Jun 2008
Posts: 784
asmcoder
[content deleted]


Last edited by asmcoder on 14 Aug 2009, 14:50; edited 1 time in total
Post 19 Jun 2009, 16:03
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Quote:

1. hooking by design is not safe. many things can go wrong and exception will occur. such as unloaded dll, next hook, etc, etc.

Remember that the injected DLL also imports the DLL that contains the function you want to hook so the target app should call FreeLibrary more times to unload than it is supposed to do (and windows really allows to unload a DLL even though it is imported by some DLL rather than just loaded via LoadLibrary?). I don't get the next hook part, if N injectors compete for the hook, only one will succeed. The rest will not crash but won't never get their hook executed. Even some of them will detect earlier their failure (because they couldn't find "mov edi, edi").

Quote:

2. imagine thread A code:



In your explanation you are assuming that the jmp will overwrite "mov ebp, esp", etc. This is not how the hooking is working. There is a jump inserted five bytes BEFORE the entry point of the function, and after that modification has been done the next thing is to replace "mov edi, edi" by the jmp instruction ("jmp $-5") which has exactly the same size than "mov edi, edi" (2 bytes, i.e. a word).
Post 19 Jun 2009, 16:40
View user's profile Send private message Reply with quote
asmcoder



Joined: 02 Jun 2008
Posts: 784
asmcoder
[content deleted]


Last edited by asmcoder on 14 Aug 2009, 14:50; edited 1 time in total
Post 19 Jun 2009, 19:12
View user's profile Send private message Reply with quote
asmcoder



Joined: 02 Jun 2008
Posts: 784
asmcoder
[content deleted]


Last edited by asmcoder on 14 Aug 2009, 14:50; edited 1 time in total
Post 19 Jun 2009, 19:16
View user's profile Send private message Reply with quote
arigity



Joined: 22 Dec 2008
Posts: 45
arigity
asmcoder wrote:
i checked krenel32 and i must admit my mistake, there ARE 5 nops and alignemt if nessecary. however smp issue still exist, 1 core wont finish mov edi,edi and another one start and end writing jmp there. and what about multiple hooks? 1 will overwrite another.

but is that rule for evry windows built-in DLL?


the whole point of the mov edi, edi and the 5 nops at the start is that so the function could be hooked for hot-patching, it should be present in most standard windows dlls.

you can do multiple hooks if your hook function ends up jumping back to the original code and so long as you end up correctly executing modified instructions before doing so.

i don't think its very likely your hooking procedure will over-write the instructions at the exact same time another processor is trying to execute them.
Post 19 Jun 2009, 19:49
View user's profile Send private message Reply with quote
asmcoder



Joined: 02 Jun 2008
Posts: 784
asmcoder
[content deleted]


Last edited by asmcoder on 14 Aug 2009, 14:50; edited 1 time in total
Post 19 Jun 2009, 20:06
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.