1

I am attempting to disassemble a test binary I compiled written in masm. Here are the follwing bytes:

    Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file X:\test.exe

File Type: EXECUTABLE IMAGE

00401000: EB FE              jmp         00401000
00401002: 33 C0              xor         eax,eax
00401004: 33 DB              xor         ebx,ebx
00401006: 33 C9              xor         ecx,ecx
00401008: 33 D2              xor         edx,edx
0040100A: B8 02 00 00 00     mov         eax,2
0040100F: BB 01 00 00 00     mov         ebx,1
00401014: 3B C3              cmp         eax,ebx
00401016: 7F 06              jg          0040101E
00401018: 2B C3              sub         eax,ebx
0040101A: 3B C3              cmp         eax,ebx
0040101C: 7F 22              jg          00401040
0040101E: B8 05 00 00 00     mov         eax,5
00401023: BB 0A 00 00 00     mov         ebx,0Ah
00401028: 3B C3              cmp         eax,ebx
0040102A: 7F 06              jg          00401032
0040102C: 2B D8              sub         ebx,eax
0040102E: 3B D8              cmp         ebx,eax
00401030: 7F 07              jg          00401039
00401032: B8 0D 00 00 00     mov         eax,0Dh
00401037: EB 0E              jmp         00401047
00401039: BB 09 00 00 00     mov         ebx,9
0040103E: EB 07              jmp         00401047
00401040: B9 17 00 00 00     mov         ecx,17h
00401045: EB 00              jmp         00401047
00401047: 6A 00              push        0
00401049: E8 00 00 00 00     call        0040104E
0040104E: FF 25 00 20 40 00  jmp         dword ptr ds:[00402000h]

The following is my python script:

import os, sys
from pydbg import *
from pydbg.defines import *

pid = int(sys.argv[1])

def handler_breakpoint(pydbg):
    if pydbg.first_breakpoint:
        return DBG_CONTINUE
    for thread_id in dbg.enumerate_threads():
        context = dbg.get_thread_context(None, h_thread)
    print("Eip = %08x" % context.Eip)
    dbg.disasm(context.Eip)
    return DBG_CONTINUE

dbg = pydbg()
dbg.set_callback(EXCEPTION_BREAKPOINT, handler_breakpoint)
dbg.attach(pid)
for thread_id in dbg.enumerate_threads():
        context = dbg.get_thread_context(None, h_thread)
dbg.bp_set(context.Eip)
dbg.resume_all_threads()
pydbg.debug_event_loop(dbg)

I just want to break into the first (jmp-0x2) instruction.

I checked the pydbg API pydbg API and various projects that utilized pydbg and couldn't make heads or tails on how to do this.

1

if you attach to any running process the breakpoint at the entry point will not be hit

to break on Address of EntryPoint you should load the binary and set the breakpoint during the first system (pydbg.firstbreakpoint)

to retrieve the AddressofEntryPoint dynamically you would have to read the process memory and decipher the pe header->address of entry point

shown below is a sample script that breaks on calc.exe entrypoint and dumps the context

:\>cat entrypoint.py
import struct
from pydbg import *
from pydbg.defines import *
def handler_breakpoint (pydbg):
  if pydbg.first_breakpoint:
    for module in dbg.iterate_modules():
      base_address = module.modBaseAddr
      dos_header   = dbg.read_process_memory(base_address, 0x40)
      if len(dos_header) != 0x40 or dos_header[:2] != "MZ":
        continue
      e_lfanew   = struct.unpack("<I", dos_header[0x3c:0x40])[0]
      pe_headers = dbg.read_process_memory(base_address + e_lfanew, 0xF8)
      if len(pe_headers) != 0xF8 or pe_headers[:2] != "PE":
        continue
      entrypoint = (struct.unpack("<I", pe_headers[0x28:0x2c])[0]) + base_addres
s
      print "0x%08x" % entrypoint
      dbg.bp_set(entrypoint)
      return DBG_CONTINUE
  print dbg.dump_context(dbg.context)
  return DBG_CONTINUE
dbg = pydbg()
dbg.set_callback(EXCEPTION_BREAKPOINT, handler_breakpoint)
dbg.load("c:\windows\system32\calc.exe")
pydbg.debug_event_loop(dbg)

result

:\>python entrypoint.py
0x01012475
CONTEXT DUMP
  EIP: 01012475 push byte 0x70
  EAX: 00000000 (         0) -> N/A
  EBX: 7ffd7000 (2147315712) -> N/A
  ECX: 0007ffb0 (    524208) ->
  EDX: 7c90e514 (2089870612) -> N/A
  EDI: 00250000 (   2424832) -> N/A
  ESI: 7c9115f9 (2089883129) -> N/A
  EBP: 0007fff0 (    524272) -> 
  ESP: 0007ffc4 (    524228) -> wp (stack)
  +00: 7c817077 (2088857719) -> N/A
  +04: 00250000 (   2424832) -> N/A
  +08: 7c9115f9 (2089883129) -> N/A
  +0c: 7ffd7000 (2147315712) -> N/A
  +10: 80544c7d (2153008253) -> N/A
  +14: 0007ffc8 (    524232) ->
  • thanks blabb! trying to avoid pefile and as many other imports as possible – grepNstepN Aug 16 '15 at 5:39
1

It looks like you'd want to indent dbg.bp_set(context.Eip) (so that it's part of the for-loop) and replace dbg.resume_all_threads() with dbg.run().

  • I tried it, and it prints EIP now. However, it doesn't print the disassembled bytes (jmp-0x2). – grepNstepN Aug 14 '15 at 19:51
  • disasm() doesn't automatically print its output; it returns its output as a string. Further questions on this would probably best be asked at stackoverflow.com. – Jason Geffner Aug 14 '15 at 20:24
  • thanks Jason! in hindsight i should have 'type()d' it to see the return type and print it or checked the definition to see if it called print – grepNstepN Aug 16 '15 at 5:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.