Results 1 to 10 of 10

Thread: Locating reference to memory address in stack of another thread

  1. #1
    shasderias
    Guest

    Locating reference to memory address in stack of another thread

    I am trying to write a program that reads some data from another program which is basically an array of 1024 16bit integers. Said program spins off a thread, the thread does some I/O with hardware and the data retrieved is stored into the array. The thread that does the reading appears to be totally self-contained, it calls another DLL that does the hardware I/O and updates the screen itself. Never communicating with the main thread. The data I need is thus stored only in a single location.

    The problem is thus: the data is stored in the stack of the thread and changes upon each program reload. How can I retrieve the address from within my own program.

    What does not (appear) to work:
    1) searching for a pointer to any point in thread's data block/stack, the thread does truly appear to be self-contained, at no point in time is there a pointer to any address within the thread's stack/data block that does not reside in the thread's own stack/data block.

    2) upon each restart, the memory allocated for the thread changes, thus I am unable to locate a static offset

    What I have considered:
    1) Trying to locate the CreateThread function, finding the address in which the handle to the thread is stored, reading that, then attempting to retrieve the thread's data block, but I am unable to determine how I can go from thread handle -> address of thread's data block

    2) injecting code/patching the program to somehow write out the memory location. The program I am working with is used for a realtime application, I do not want to risk crashing it

    Any advice is appreciated, thank you

    Some extra information I am unsure if it would be useful:
    1) Program written in Delphi6
    2) The data is always stored at a fixed offset from the thread's stack, if I can somehow get the base address of the thread, I'd be fine
    3) There are multiple threads spun off for different purposes, considered enumerating the threads, picking the one that isn't the main thread, does not work for this reason
    4) Data block of thread has a pointer to the thread's stack, thus the address of the data block would work just fine
    Last edited by shasderias; June 30th, 2010 at 11:32.
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  2. #2
    |< x != '+' BanMe's Avatar
    Join Date
    Oct 2008
    Location
    Farmington NH
    Posts
    510
    Blog Entries
    4

    well there are tons of fun ways to solve this...but heres 1 of the simplest..

    Code:
    HANDLE WINAPI CreateThread(
      __in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
      __in       SIZE_T dwStackSize,
      __in       LPTHREAD_START_ROUTINE lpStartAddress,
      __in_opt   LPVOID lpParameter,
      __in       DWORD dwCreationFlags,
      __out_opt  LPDWORD lpThreadId
    );
    You can breakpoint CreateThread(if you can debug the process that is)then you would need to filter out the lpStartAddress of each call to the function (and maybe the lpParameter passed just for further identification) then you could develop a 'signature' to scan for the function you know the thread uses and has your specific data or 'will' have it. You can then either hook the function and gather the data that way or you can use Stackwalk64() to walk the stack of all threads and locate your data in a more meticulous way

    I think the more reliable method is the hook cause it update on call and not user demand but to each his\her own.

    regards BanMe
    No hate for the lost children;
    more love for the paths we walk,
    'words' shatter the truth we seek.
    from the heart and mind of Me
    me, to you.. down and across

    No more words from me, to you...
    Hate and love shatter the heart and Mind of Me.
    For the Lost Children;For the paths we walk; the real truth we seek!

  3. #3
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,114
    Blog Entries
    5
    Hi

    Just a few ideas. You could probably manage that with a driver, making use of KeStackAttachProcess. Once you've attached to the process you'll need to reference the correct thread. You could parse through all the threads in the process and cross reference with the known Win32StartAddress to get the correct thread object. Or, if you've previously determined the thread handle from usermode, you should be able to convert that to the correct thread object (ETHREAD structure) with ObReferenceObjectByHandle.

    ETHREAD.TEB will reference NT_TIB and NT_TIB.StackBase will give you the stack reference offset you need (EBP may be directly available as well through some combination of structure offsets) . Since you're attached to the process you should be able to read it.

    I did a little test under Softice and was able to find a local variable on a thread stack by manually parsing the ETHREAD in that manner.

    Interested in any other strategies.

    Kayaker

  4. #4
    shasderias
    Guest
    Quote Originally Posted by BanMe View Post
    Code:
    HANDLE WINAPI CreateThread(
      __in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
      __in       SIZE_T dwStackSize,
      __in       LPTHREAD_START_ROUTINE lpStartAddress,
      __in_opt   LPVOID lpParameter,
      __in       DWORD dwCreationFlags,
      __out_opt  LPDWORD lpThreadId
    );
    You can breakpoint CreateThread(if you can debug the process that is)then you would need to filter out the lpStartAddress of each call to the function (and maybe the lpParameter passed just for further identification) then you could develop a 'signature' to scan for the function you know the thread uses and has your specific data or 'will' have it.
    Yup, I can debug the process no problem, the relevant CreateThread call always passes in the same value for ThreadFunction. I also know the function that makes the external DLL call. Should I try hooking either the external DLL call instead?

    I am still not quite sure how I should do this from within my own program though, specifically how do I scan for the function, or am I supposed to set a breakpoint from my own program on the process? A pointer at the correct direction would be appreciated.

    You can then either hook the function and gather the data that way or you can use Stackwalk64() to walk the stack of all threads and locate your data in a more meticulous way

    I think the more reliable method is the hook cause it update on call and not user demand but to each his\her own.

    regards BanMe
    Indeed, looks like the hook is a better solution, given that the application calls out once every second or so.

    I'm guessing my problem is, I can see all the information I need in Olly, I just am not sure how to translate that to code.

    Kayaker
    Hi

    Just a few ideas. You could probably manage that with a driver, making use of KeStackAttachProcess. Once you've attached to the process you'll need to reference the correct thread. You could parse through all the threads in the process and cross reference with the known Win32StartAddress to get the correct thread object. Or, if you've previously determined the thread handle from usermode, you should be able to convert that to the correct thread object (ETHREAD structure) with ObReferenceObjectByHandle.

    ETHREAD.TEB will reference NT_TIB and NT_TIB.StackBase will give you the stack reference offset you need (EBP may be directly available as well through some combination of structure offsets) . Since you're attached to the process you should be able to read it.

    I did a little test under Softice and was able to find a local variable on a thread stack by manually parsing the ETHREAD in that manner.

    Interested in any other strategies.

    Kayaker
    Apologies, unfamiliar with Windows drivers: basically I would need to write a small driver that grabs the necessary data (I get the gist of the procedure you've outlined), and/or somehow retrieve a handle to the process in usermode, pass that to the driver, which would then call ObReferenceObjectByHandle, giving me an ETHREAD object, which I can use to locate the memory offsets I need. Following which I can read the process's memory from usermode to get the data structure out. Is that right?

    Thanks for the help Banme and Kayaker (:
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  5. #5
    http://wiki.tcwonline.org/Signature_Scanning

    Data block of thread has a pointer to the thread's stack
    Is the address of the data block being passed as lpParameter to the CreateThread function?

  6. #6
    shasderias
    Guest
    Quote Originally Posted by aqrit View Post
    http://wiki.tcwonline.org/Signature_Scanning



    Is the address of the data block being passed as lpParameter to the CreateThread function?
    Nope, appears to be the return value of a function called a few lines up. Thanks, reading (:

    edit: That was what I was thinking, scanning for a series of bytes unique to the thread's stack/data block. Looking into that now, failing which, will probably try to hook the I/O dll's function/function that calls the I/O function.

    edit2: I don't quite understand how getting the address of the function helps me. The function is always located at a fixed offset, its the thread's data block/stack that shifts around.
    Last edited by shasderias; July 1st, 2010 at 02:10.
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  7. #7
    |< x != '+' BanMe's Avatar
    Join Date
    Oct 2008
    Location
    Farmington NH
    Posts
    510
    Blog Entries
    4

    How having the 'address' of your specific function Helps you..

    I also know the function that makes the external DLL call. Should I try hooking either the external DLL call instead?
    You can do that.

    How do I scan for the function, or am I supposed to set a breakpoint from my own program on the process? A pointer at the correct direction would be appreciated.
    well the answer to that is Dll or memory Injection you cant rely on your own process to have this data and if you set a breakpoint on the function from your code you would also have to add a handler to handler the Breakpoint you wrote in said process..unless you want it to break to olly..or w/e

    lets do a little sample of how to find code by scanning for it (In our own process)
    Code:
    2147102C > $ 68 48010000    PUSH 148
    21471031   . 68 28224721    PUSH affectio.21472228
    21471036   . E8 11050000    CALL affectio.__SEH_prolog
    2147103B   . 33DB           XOR EBX,EBX
    2147103D   . 895D AC        MOV DWORD PTR SS:[EBP-54],EBX
    21471040   . 33C0           XOR EAX,EAX
    21471042   . 8D7D B0        LEA EDI,DWORD PTR SS:[EBP-50]
    21471045   . AB             STOS DWORD PTR ES:[EDI]
    21471046   . AB             STOS DWORD PTR ES:[EDI]
    21471047   . 895D 94        MOV DWORD PTR SS:[EBP-6C],EBX
    2147104A   . 33C0           XOR EAX,EAX
    2147104C   . 8D7D 98        LEA EDI,DWORD PTR SS:[EBP-68]
    2147104F   . AB             STOS DWORD PTR ES:[EDI]
    21471050   . AB             STOS DWORD PTR ES:[EDI]
    21471051   . 66:895D D8     MOV WORD PTR SS:[EBP-28],BX
    21471055   . 33C0           XOR EAX,EAX
    21471057   . 8D7D DA        LEA EDI,DWORD PTR SS:[EBP-26]
    2147105A   . AB             STOS DWORD PTR ES:[EDI]
    2147105B   . 66:AB          STOS WORD PTR ES:[EDI]
    2147105D   . C745 A0 964000>MOV DWORD PTR SS:[EBP-60],4096
    21471064   . 33C0           XOR EAX,EAX
    21471066   . 8D7D A4        LEA EDI,DWORD PTR SS:[EBP-5C]
    21471069   . AB             STOS DWORD PTR ES:[EDI]
    2147106A   . 66:899D FCFEFF>MOV WORD PTR SS:[EBP-104],BX
    21471071   . 6A 7E          PUSH 7E                                  ; /n = 7E (126.)
    21471073   . 53             PUSH EBX                                 ; |c => 00
    21471074   . 8D85 FEFEFFFF  LEA EAX,DWORD PTR SS:[EBP-102]           ; |
    2147107A   . 50             PUSH EAX                                 ; |s
    2147107B   . E8 22060000    CALL affectio._memset                    ; \_memset
    21471080   . 66:899D A8FEFF>MOV WORD PTR SS:[EBP-158],BX
    21471087   . 6A 52          PUSH 52                                  ; /n = 52 (82.)
    21471089   . 53             PUSH EBX                                 ; |c
    2147108A   . 8D85 AAFEFFFF  LEA EAX,DWORD PTR SS:[EBP-156]           ; |
    21471090   . 50             PUSH EAX                                 ; |s
    21471091   . E8 0C060000    CALL affectio._memset                    ; \_memset
    21471096   . 83C4 18        ADD ESP,18
    21471099   . 899D 7CFFFFFF  MOV DWORD PTR SS:[EBP-84],EBX
    ...
    ok so for this eample we want to find memset.
    so the opcode just after memset are..

    Code:
     83C4 18        ADD ESP,18
    heres the signature that we will find this code

    Code:
    BYTE FindThis[] = {0x83,0xc4,0,0x04};
    // this says find opcodes 0x83 and 0xc4 in consecutive order
    //ie the 0 after the opcodes, after our function finds these opcodes it minus's 0x4
    //for the address they where found at to get the function call to memset
    This functionality is illustrated in this code
    Code:
    //This Code is a mix of methods ive come accross 
    //GetFunctionLength is a knock off of what darawk did with a similiar name..can be googled..
    //Signature Scanning code I think I originally saw this technique by opcodex90..
    //secondly this dynamic find methodology was first implemented in CsrWalker by ep_xoff or ug_north...
    //I just combined them into something I found had a good amount of speed and get it right 99% of the time..
    //(if you have a unique signature and it cant be found after the start of the function and is -(n) 
    //away from the address the opcodes where found at..
    ULONG FindCode(__in ULONG dwStart,__in BYTE *FindThis)
    {
    	
    	ULONG ProcEnd = 0;					
    	ProcEnd = GetFunctionLength((void*)dwStart);
    	ProcEnd += dwStart;
    	do
    	{
    		if(memcmp((void*)dwStart,&FindThis[0],sizeof(BYTE)) == 0 && memcmp((void*)(dwStart+sizeof(BYTE)+(ULONG)FindThis[2]),&FindThis[1],sizeof(BYTE)) == 0)
    		{
    			return (ULONG)(dwStart - (ULONG)FindThis[3]);
    		}
    		(BYTE*)dwStart++;
    	}while(dwStart < ProcEnd);
    	ProcEnd = 0;
    	return ProcEnd;
    }
    This code can be use without the functions Ive placed in it though it could end up scanning memory that doesnt like to be scanned.

    I don't quite understand how getting the address of the function helps me. The function is always located at a fixed offset, its the thread's data block/stack that shifts around.
    The fact the function is static is a good thing this means you can reliably hook it without worry of false positives(scans for the function) ie hooking the wrong location and causing instability in the program..

    but from what you describe i gather the pseudocode of said program

    Code:
    uint Buff[1024] = {0};//This is either passed by reference or it is a global block of memory
    // or is just on the stack..
    SomeOtherCode...
    FunctionThatFillsBuff()
    //here you want to hook..
    The Data you want is there after return from said function, you can either place the hook or some other form of 'code derailment' instrumentation(VEH exceptions,SEH Exceptions,int3,PAGE_NO_ACCESS,PAGE_GAURD..to name a few..) If the hook is placed here you will have to emulate the opcodes overwritten in your hook before return to original program flow if the hook is placed on the function that will make it a bit more time consuming to build the hook routines..
    If FunctionThatFills Buff returns in EAX your golden at this point if not in eax and just on stack
    You can do as kayaker suggests with a lil modifiication(and not use a driver). NtCurrentTeb()->NtTib.StackBase could easily be used in the hook code to get that address

    regards BanMe
    Last edited by BanMe; July 2nd, 2010 at 13:12.
    No hate for the lost children;
    more love for the paths we walk,
    'words' shatter the truth we seek.
    from the heart and mind of Me
    me, to you.. down and across

    No more words from me, to you...
    Hate and love shatter the heart and Mind of Me.
    For the Lost Children;For the paths we walk; the real truth we seek!

  8. #8
    shasderias
    Guest
    Quote Originally Posted by BanMe View Post
    The fact the function is static is a good thing this means you can reliably hook it without worry of false positives(scans for the function) ie hooking the wrong location and causing instability in the program..

    but from what you describe i gather the pseudocode of said program

    Code:
    uint Buff[1024] = {0};//This is either passed by reference or it is a global block of memory
    // or is just on the stack..
    SomeOtherCode...
    FunctionThatFillsBuff()
    //here you want to hook..
    The Data you want is there after return from said function, you can either place the hook or some other form of 'code derailment' instrumentation(VEH exceptions,SEH Exceptions,int3,PAGE_NO_ACCESS,PAGE_GAURD..to name a few..) If the hook is placed here you will have to emulate the opcodes overwritten in your hook before return to original program flow if the hook is placed on the function that will make it a bit more time consuming to build the hook routines..
    If FunctionThatFills Buff returns in EAX your golden that this point if not in eax and just on stack
    You can do as kayaker suggests with a lil modifiication(and not use a driver). NtCurrentTeb()->NtTib.StackBase could easily be used in the hook code to get that address

    regards BanMe
    Yup! Thats more or less exactly what the code looks like, and after some thought, that is probably the best way out. Finding the address and polling isn't as good a idea as the duration between each call to the IO function is variable (controlled by the user).

    Buffer is created way earlier in the code, pointer to it is passed through several functions, before finally arriving here, ReadRegisters returns on AX I believe, value is stored somewhere else for some other purpose :

    004C3205 CALL <JMP.&ML2DRV.ReadRegisters> ; ReadRegisters = function that does IO
    004C320A MOV WORD PTR DS:[EDI+44],AX ;
    004C320E JMP USW_up.004C32B8 ; goes somewhere else not as interesting

    So. Currently reading up on hooking, but is what I need to learn and do something like:
    1) inject my own block of code into the function (getting some space using VirtualAllocEx, then probably using CreateRemoteThread to run the code)
    2) patch either 004C320A or 004C320E to jump into my block of code, push registers onto the stack
    3) run my own code, NtCurrentTeb()->NtTib.StackBase gets me the address of the stack I want, use the offset, do whatever I need to do
    4)
    a) if patching 320A, move AX into EDI+44, then jump back to 320E
    b) if patching 320E, jump to 004C32B8 when my code is done
    5) restore the registers

    Time to learn function hooking (:
    Thanks again!
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  9. #9
    |< x != '+' BanMe's Avatar
    Join Date
    Oct 2008
    Location
    Farmington NH
    Posts
    510
    Blog Entries
    4
    It can work like that yes

    good luck.

    regards BanMe
    No hate for the lost children;
    more love for the paths we walk,
    'words' shatter the truth we seek.
    from the heart and mind of Me
    me, to you.. down and across

    No more words from me, to you...
    Hate and love shatter the heart and Mind of Me.
    For the Lost Children;For the paths we walk; the real truth we seek!

  10. #10
    shasderias
    Guest

    got it!

    Got it!

    Wrote a little DLL, injected it into the process, patches the JMP to point at my own function, function gets called in context of relevant thread, do my memory shuffling, NtCurrentTeb->StackBase gives you the address of the current thread, do some offset calculations. Viola

    Couldn't have done it without all your help. Thanks!
    I promise that I have read the FAQ and tried to use the Search to answer my question.

Similar Threads

  1. Finding memory address of a .net application at runtime?
    By mr_tex in forum The Newbie Forum
    Replies: 0
    Last Post: November 24th, 2013, 20:43
  2. Conditional Hardware break on memory address not working
    By OpenStrife in forum OllyDbg Support Forums
    Replies: 3
    Last Post: March 18th, 2013, 23:06
  3. How to find all rows/lines with a specific memory address?
    By tDJ in forum OllyDbg Support Forums
    Replies: 4
    Last Post: October 21st, 2005, 01:26
  4. how to break when a memory address is accessed?
    By mcnorth in forum OllyDbg Support Forums
    Replies: 3
    Last Post: September 13th, 2005, 19:27
  5. ASProtect high memory address trick
    By Solomon in forum Malware Analysis and Unpacking Forum
    Replies: 0
    Last Post: March 18th, 2004, 11:15

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •