Skip to content

Instantly share code, notes, and snippets.

@patois
Created April 12, 2020 18:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patois/c83554d487adf1b4e84990fa23b1a647 to your computer and use it in GitHub Desktop.
Save patois/c83554d487adf1b4e84990fa23b1a647 to your computer and use it in GitHub Desktop.
jmplog.asm
.386
.model flat,stdcall
option casemap:none
include include\windows.inc
include include\kernel32.inc
include include\comdlg32.inc
include include\user32.inc
includelib lib\kernel32.lib
includelib lib\comdlg32.lib
includelib lib\user32.lib
.data
AppName db "JumpLogger v1.0",0
ofn OPENFILENAME <>
FilterString db "Executable Files",0,"*.exe",0
db "All Files",0,"*.*",0,0
ExitProc db "The debuggee exits",0
TotalInstruction dd 0
LogFile db 'jumplog.log',0
Handle dd 0
THandle dd 0
written dd 0
FileAttr dd 0
ReportInts db 1
RVA db 8 dup(0)
db ': '
JumpAddr db 8 dup(0)
db ' '
_Flags db 0
db 'Flags: '
Overflow db 0
Direction db 0
Interrupt db 0
Trap db 0
Sign db 0
Zero db 0
Auxiliary db 0
Parity db 0
Carry db 0
SizeOfFlags equ $-offset _Flags-1
Code db 8 dup(0)
db 8 dup(020h)
Opcode dd 0
backup dd 0
CRLF db 13,10
ProcHandle dd 0
Opcodes db 077h ;opcode-table for conditional jumps listed below
db 073h
db 072h
db 076h
db 0E3h
db 074h
db 07Fh
db 07Dh
db 07Ch
db 07Eh
db 075h
db 071h
db 07Bh
db 079h
db 070h
db 07Ah
db 078h
mnemonics db 0 ;list of mnemonics used for disassembly
_JA db 'ja '
_JAE db 'jae '
_JB db 'jb '
_JBE db 'jbe '
_JCXZ db 'jcxz '
_JZ db 'jz '
_JG db 'jg '
_JGE db 'jge '
_JL db 'jl '
_JLE db 'jle '
_JNZ db 'jnz '
_JNO db 'jno '
_JNP db 'jnp '
_JNS db 'jns '
_JO db 'jo '
_JP db 'jp '
_JS db 'js '
msg db 'Possible Debugger detection! Try to remove (lame patching)?',0
cap db 'hmmm...',0
NopArray db 10 dup(090h)
.data?
buffer db 512 dup(?)
startinfo STARTUPINFO <>
pi PROCESS_INFORMATION <>
DBEvent DEBUG_EVENT <>
align dword
context CONTEXT <>
.code
main:
mov [FileAttr],0 ;parameters for GetOpenFileName
mov ofn.lStructSize,SIZEOF ofn
mov ofn.lpstrFilter, OFFSET FilterString
mov ofn.lpstrFile, OFFSET buffer
mov ofn.nMaxFile,512
mov ofn.Flags, OFN_FILEMUSTEXIST or \
OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
OFN_EXPLORER or OFN_HIDEREADONLY
invoke GetOpenFileName, ADDR ofn ;open dialog
.if eax==TRUE
;##################
;create log-file (file will always be overwritten, if previously existed)
invoke CreateFileA,ADDR LogFile,GENERIC_READ or GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
mov [Handle],eax
;#################
;Create the process of the chosen .exe
;and handle debug-events
invoke GetStartupInfo,addr startinfo
invoke CreateProcess, addr buffer, NULL, NULL, NULL, FALSE, DEBUG_PROCESS+ DEBUG_ONLY_THIS_PROCESS, NULL, NULL, addr startinfo, addr pi
.while TRUE
invoke WaitForDebugEvent, addr DBEvent, INFINITE ;'suspend' our debugger until an
.if DBEvent.dwDebugEventCode==CREATE_PROCESS_DEBUG_EVENT ;exception occurs
mov eax,DBEvent.u.CreateProcessInfo.hProcess
mov [ProcHandle], eax ;skip the ep-exception
.elseif DBEvent.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT ;process killed/exited ?
invoke MessageBox, 0, addr buffer, addr AppName, MB_OK+MB_ICONINFORMATION
.break
.elseif DBEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT ;breakpoint?
.if DBEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT
mov context.ContextFlags, CONTEXT_CONTROL
invoke GetThreadContext, pi.hThread, addr context ;'pop' registers
or context.regFlag,100h ;set trap-flag
invoke SetThreadContext,pi.hThread, addr context ;'push' registers
invoke ContinueDebugEvent, DBEvent.dwProcessId,DBEvent.dwThreadId,DBG_CONTINUE ;continue debuggee
.continue
.elseif DBEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_SINGLE_STEP ;set the trapflag previously?
invoke GetThreadContext,pi.hThread,addr context ;get flags and other shit
call Log ;call a poorly commented log-procedure
or context.regFlag,100h ;set the trap flag
invoke SetThreadContext,pi.hThread, addr context ;ficke,ficke
invoke ContinueDebugEvent, DBEvent.dwProcessId,DBEvent.dwThreadId,DBG_CONTINUE
.continue
.endif
.endif
invoke ContinueDebugEvent, DBEvent.dwProcessId,DBEvent.dwThreadId,DBG_EXCEPTION_NOT_HANDLED ;this must be window's or coder's fault ;)
.endw
.endif
;#################
;fixup and stuff...
invoke TerminateProcess,pi.hProcess,0 ;quit debugee
invoke CloseHandle,pi.hProcess ;close handle for debugee
invoke CloseHandle,pi.hThread
invoke CloseHandle,Handle
invoke ExitProcess,0 ;exit JumpLog
;#################
;some procs
;converts a dword into hexadecimal format and copies it to a given string buffer
DecToHex Proc
mov ecx,8 ;init counter
xor ebx, ebx
mov eax, [esp+4] ;1st param = decimal(dword) to convert
mov edi, [esp+8] ;2nd param = pointer to ascii-buffer
calc:
dec ecx ;decrement counter
mov bl, al
shl bl,4
shr bl,4
add bl, 030h
cmp bl,3Ah
jb nofix
add bl,7
nofix:
mov byte ptr [edi+ecx],bl
dec ecx
mov bl, al
shr bl,4
add bl, 030h
cmp bl,3Ah
jb nofix2
add bl,7
nofix2:
mov byte ptr [edi+ecx],bl
shr eax,8
test ecx, ecx
jnz calc
ret 8
DecToHex endp
;#################
;create disassembly and collect some shitty info and write it to our logfile
Log Proc
pushad ;save all regs
invoke ReadProcessMemory, [ProcHandle], context.regEip ,ADDR Opcode, 4, ADDR written ;read 4 bytes at EIP
mov ebx,[Opcode]
mov [backup],ebx
;#################
;check for conditional jumps
cmp bl, 074h ;jz ?
jz GetFlags
cmp bl, 075h ;jnz?
jz GetFlags
cmp bl, 07Dh ;jge ?
jz GetFlags
cmp bl, 07Fh ;jg ?
jz GetFlags
cmp bl, 077h ;ja ?
jz GetFlags
cmp bl, 073h ;jae ?
jz GetFlags
cmp bl, 072h ;jb ?
jz GetFlags
cmp bl, 076h ;jbe ?
jz GetFlags
cmp bl, 0E3h ;jcxz ?
jz GetFlags
cmp bl, 07Ch ;jl ?
jz GetFlags
cmp bl, 07Eh ;jle ?
jz GetFlags
cmp bl, 071h ;jno ?
jz GetFlags
cmp bl, 07Bh ;jnp ?
jz GetFlags
cmp bl, 079h ;jns ?
jz GetFlags
cmp bl, 070h ;jo ?
jz GetFlags
cmp bl, 07Ah ;jp ?
jz GetFlags
cmp bl, 078h ;js ?
jz GetFlags
;#################
;check for possible sice detections
;int 3 ?
cmp bl, 0CCh
jz int3call
;int 1 ?
cmp bx, 001CDh
jz intcall
;int 68h ?
cmp bx, 068CDh
jz intcall
;no more sice detections included ;)
jmp skip
GetFlags:
mov eax, context.regFlag ;store flags into eax
;#################
;test for specific flags
CheckC:
test eax, 0000000000000001b
jnz Cset
mov [Carry],'c'
jmp CheckP
Cset:
mov [Carry],'C'
CheckP:
test eax, 0000000000000100b
jnz Pset
mov [Parity],'p'
jmp CheckA
Pset:
mov [Parity],'P'
CheckA:
test eax, 0000000000010000b
jnz Aset
mov [Auxiliary],'a'
jmp CheckZ
Aset:
mov [Auxiliary],'A'
CheckZ:
test eax, 0000000001000000b
jnz Zset
mov [Zero],'z'
jmp CheckS
Zset:
mov [Zero],'Z'
CheckS:
test eax, 0000000010000000b
jnz Sset
mov [Sign],'s'
jmp CheckT
Sset:
mov [Sign],'S'
CheckT:
test eax, 0000000100000000b
jnz Tset
mov [Trap],'t'
jmp CheckI
Tset:
mov [Trap],'T'
CheckI:
test eax, 0000001000000000b
jnz Iset
mov [Interrupt],'i'
jmp CheckD
Iset:
mov [Interrupt],'I'
CheckD:
test eax, 0000010000000000b
jnz Dset
mov [Direction],'d'
jmp CheckO
Dset:
mov [Direction],'D'
CheckO:
test eax, 0000100000000000b
jnz Oset
mov [Overflow],'o'
jmp done
Oset:
mov [Overflow],'O'
done:
push offset RVA
push context.regEip
call DecToHex ;convert current eip to hex for the dump to log-file
mov eax,[Opcode] ;erm, lame routine to swap some bytes
mov bl,al
mov cl,ah
mov ah,bl
mov al,cl
shl eax, 16
mov [Opcode], eax
push offset Code
push [Opcode]
call DecToHex ;convert the opcode to hex
mov dword ptr [Code+4],020202020h ;add some spaces
;#################
;write to log-file
invoke WriteFile,[Handle],ADDR RVA,10,ADDR written,0 ;write eip to log
invoke WriteFile,[Handle],ADDR Code,10,ADDR written,0 ;write opcodes
;#################
;create disassembly opcode
;int 3
cld
mov ecx,17
mov eax, [backup]
mov edi, offset Opcodes
repnz scasb
mov edx, 17
sub edx, ecx
mov esi, offset mnemonics
inc esi
dec edx
mov eax,5
mul edx
add esi, eax
invoke WriteFile,[Handle],esi,5,ADDR written,0
;create disassembly operand
mov eax, context.regEip
mov ebx,[backup]
add bh,2
add al, bh
push offset JumpAddr
push eax
call DecToHex
invoke WriteFile,[Handle],ADDR JumpAddr,10,ADDR written,0
invoke WriteFile,[Handle],ADDR _Flags+1,SizeOfFlags,ADDR written,0
invoke WriteFile,[Handle],addr CRLF,2,ADDR written,0
skip:
popad
ret
int3call:
cmp [ReportInts],0
jz skip
invoke MessageBoxA,0,addr msg,addr cap,MB_YESNOCANCEL+MB_ICONEXCLAMATION
cmp eax,IDNO ;no ?
jz skip
cmp eax,IDCANCEL
jz neverask
invoke WriteProcessMemory,[ProcHandle],context.regEip ,addr NopArray, 1, NULL
jmp skip
intcall:
cmp [ReportInts],0
jz skip
invoke MessageBoxA,0,addr msg,addr cap,MB_YESNOCANCEL+MB_ICONEXCLAMATION
cmp eax,IDNO ;no ?
jz skip
invoke WriteProcessMemory,[ProcHandle],context.regEip ,addr NopArray, 2, NULL
jmp skip
neverask:
mov [ReportInts],0
jmp skip
Log endp
end main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment