开发者

How can I find byte sequences in memory on a Windows XP/7 box?

Problem: I'm working on a project for school (my choice) which is a program loader/DLL injector, the idea of which I initially found here, modified to suit my needs, and converted the ASM portions of the DLL to extended ASM that will compile with GCC instead of Visual Studio. Rather than do the pinball score print in a console window thing, I'm loading a program I wrote that takes input from a user and writes it to a file. The loader injects a DLL with a function in it that redirects user input, formerly destined for a file, to a messagebox, and will write my own string to the file.

It works on my machine, however, I have concerns about platform switching because my professor has to compile the work on her machine, so it is possible that the address 0x004014A6, which currently contains the instruction to CALL <some address> which writes that string to a file(the actual code is: ofile << user_input;) won't conta开发者_运维问答in anything close to that when compiled on another machine, but will still have a call to that function that writes a string to a file.

What I want to do is dynamically determine what that address will be, as opposed to hardcoding the address. I think I can do this by using GetProcAddress on the function that gets called to get the address, then create an array to hold the bytes representing CALL <that function>, and search byte by byte in memory somewhere around where I expect to find that call to be made, take the address, and work from there.

I don't know exactly how to do that, though.

MAIN QUESTION: How can I scan a range of memory addresses and compare the contents to elements of an array?

Put another way, I want to include in my DLL a function that reads bytes at an arbitrary address in memory and compares it to an expected sequence. How can I just arbitrarily read contents of memory addresses within a certain process?

Suspicions: I'll need to know the starting and ending addresses where execution of the original program takes place. How can I get the range between starting and ending addresses? (This seems like the real hurdle here. I can probably get the rest knowing only how to obtain the processes beginning and ending addresses.)


Unless the version of the program is your targeting is gonna change soon, you can use VA(virtual address) = RVA(relative virtual address) + module Base load address(which can be gotten with GetModuleHandle) to get an address that won't fail under different systems. If the version does change, then your looking at a signature scanner. They aren't foolproof however, as the patterns your scanning for can radically change from one build to the next. Any range data needed can be gotten from the PE of the targetted app, that can then be used to temporarily apply read privilages to the .code section, allowing you to loop through it efficiently(the not so efficient was is to use ReadProcessMemory). Here is a small sigscanner lib, farther down is also a link to source for a simple sig scanner: http://www.blizzhackers.cc/viewtopic.php?f=182&t=478228&sid=55fc9a949aa0beb2ca2fb09e933210de


If you are using Python, maybe ptrace could help. It is cross-platfrom, and could be installed from pip. Here's a code snip for unix that I grabbed here: http://sixserv.org/2010/07/26/memory-debugging-or-a-universal-game-trainer-with-python-and-ptrace/

def search_memory_locations(pid, max_memory, search_value):
    child_pid = os.fork()
    if child_pid == 0: # search within forked process:
        locations = list()
        prev_locations = read_locations()

        dbg = PtraceDebugger()
        process = dbg.addProcess(pid, False)
        memory_mappings = readProcessMappings(process)

        print "\x1B[?25l", # deactivate cursor (^_^)
        for memory_mapping in memory_mappings:
            # only search in read/writable memory areas within range...
            if "rw" in memory_mapping.permissions and memory_mapping.end <= max_memory:
                for loc in range(memory_mapping.start, memory_mapping.end):
                    value = process.readBytes(loc, 1)
                    if value[0] == search_value:
                        print "search memory area[0x%08X-0x%08X] address[0x%08X] value[0x%02X (%03d)]   \r" % (memory_mapping.start, memory_mapping.end, loc, ord(value), ord(value)),

                        if prev_locations and len(prev_locations) > 0 and not loc in prev_locations:
                            continue # skip prev not found locations

                        locations.append(loc)
        print "\x1B[?25h", # activate cursor
        dbg.quit()
        write_locations(locations)
        sys.exit()

    return child_pid # don't really need this

If you are using C/C++, here's a function specific for Windows that I used before from ITH (http://code.google.com/p/interactive-text-hooker/):

DWORD SearchPattern(DWORD base, DWORD base_length, LPVOID search, DWORD search_length) //KMP
{
    __asm
    {
        mov eax,search_length
alloc:
        push 0
        sub eax,1
        jnz alloc

        mov edi,search
        mov edx,search_length 
        mov ecx,1
        xor esi,esi
build_table:
        mov al,byte ptr [edi+esi]
        cmp al,byte ptr [edi+ecx]
        sete al
        test esi,esi
        jz pre
        test al,al
        jnz pre
        mov esi,[esp+esi*4-4]
        jmp build_table
pre:
        test al,al
        jz write_table
        inc esi
write_table:
        mov [esp+ecx*4],esi

        inc ecx
        cmp ecx,edx
        jb build_table

        mov esi,base
        xor edx,edx
        mov ecx,edx
matcher:
        mov al,byte ptr [edi+ecx]
        cmp al,byte ptr [esi+edx]
        sete al
        test ecx,ecx
        jz match
        test al,al
        jnz match
        mov ecx, [esp+ecx*4-4]
        jmp matcher
match:
        test al,al
        jz pre2
        inc ecx
        cmp ecx,search_length
        je finish
pre2:
        inc edx
        cmp edx,base_length //search_length
        jb matcher
        mov edx,search_length
        dec edx
finish:
        mov ecx,search_length
        sub edx,ecx
        lea eax,[edx+1]
        lea ecx,[ecx*4]
        add esp,ecx
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜