How to skip a line from execution in windbg everytime it hits? - windbg

Suppose I want to skip line 3 of function func everytime it is called
int func() {
int a = 10, b =20;
a = 25;
b = 30;
return a+b
}
so everytime It should be returning 40 (ie doesn't execute 3rd line a=25)
Is there any similar command in windbg like jmp in gdb?

again a very late answer but if messing with assembly is not preferable
set a conditional breakpoint to skip executing one line
in the example below 401034 is the line you do not want to execute
so set a conditional breakpoint on that line to skip it
bp 401034 "r eip = #$eip + size of current instruction";gc"
7 in this case gc = go from conditionl break
jmptest:\>dir /b
jmptest.c
jmptest:\>type jmptest.c
#include <stdio.h>
int func()
{
int a = 10 , b = 20;
a = 25;
b = 30;
return a+b;
}
int main (void)
{
int i , ret;
for (i= 0; i< 10; i++)
{
ret = func();
printf("we want 40 we get %d\n",ret);
}
return 0;
}
jmptest:\>cl /nologo /Zi jmptest.c
jmptest.c
jmptest:\>dir /b *.exe
jmptest.exe
jmptest:\>cdb -c "uf func;q" jmptest.exe | grep 401
00401020 55 push ebp
00401021 8bec mov ebp,esp
00401023 83ec08 sub esp,8
00401026 c745fc0a000000 mov dword ptr [ebp-4],0Ah
0040102d c745f814000000 mov dword ptr [ebp-8],14h
00401034 c745fc19000000 mov dword ptr [ebp-4],19h
0040103b c745f81e000000 mov dword ptr [ebp-8],1Eh
00401042 8b45fc mov eax,dword ptr [ebp-4]
00401045 0345f8 add eax,dword ptr [ebp-8]
00401048 8be5 mov esp,ebp
0040104a 5d pop ebp
0040104b c3 ret
jmptest:\>cdb -c "bp 401034 \"r eip = 0x40103b;gc\";g;q " jmptest.exe | grep wan
t
we want 40 we get 40
we want 40 we get 40
we want 40 we get 40
we want 40 we get 40
we want 40 we get 40
we want 40 we get 40
we want 40 we get 40
we want 40 we get 40
we want 40 we get 40
we want 40 we get 40
jmptest:\>

If you're familiar with assembly, you can use the a command to change the assembly (i.e. turn the opcodes for, "a = 25;" into all NOPs). This is what I typically do when I want to NOP out or otherwise change an instruction stream.
Occasionally people will rely on the fact that the byte code for the NOP instruction is 0x90 and use the e command to edit the memory (e.g. "ew #eip 0x9090"). This is the same result as using the a command.
Lastly, if you're hitting this operation infrequently and just want to manually skip the instruction you can use the, "Set Current Instruction" GUI operation:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542851(v=vs.85).aspx

There is a tutorial here that explains how to do this, you can set the offset so that it skips the line: http://cfc.kizzx2.com/index.php/tutorial-using-windbg-to-bypass-specific-functions-windbg-kung-fu-series/ and set the register eip to this value.
Also, you can set the breakpoint and put the command into the breakpoint to do the same: http://japrogbits.blogspot.co.uk/2010/01/using-breakpoints-to-skip-function-in.html and another blog: http://www.shcherbyna.com/?p=1234 and also you can use the .call to achieve the same: http://blogs.msdn.com/b/oldnewthing/archive/2007/04/27/2292037.aspx

Related

Calculating jmp's from one segment to another in windows PE files

Assume I have a binary on my disk that I load into memory using VirtualAlloc and ReadFile.
If I want to follow a jmp instruction from one section to another, what do I need to add/subtract to get the destination address.
In other words, I want to know how IDA calculates the loc_140845BB8 from jmp loc_140845BB8
Example:
.text:000000014005D74E jmp loc_140845BB8
Jumps to the section seg007
seg007:0000000140845BB8 ; seg007:0000000140845BC4↓j
seg007:0000000140845BB8 and rbx, r14
PE info (seg007 is the section named "")
Segments are arbitary, it jumps where it jumps, without regard for segments. Jump location is calculated as the signed 32-bit value following the 0xE9 JMP opcode, added to the the address of where the next instruction would be (i.e. the location of JMP + 5 bytes).
def GetInsnLen(ea):
insn = ida_ua.insn_t()
return ida_ua.decode_insn(insn, ea)
def MakeSigned(number, size):
number = number & (1<<size) - 1
return number if number < 1<<size - 1 else - (1<<size) - (~number + 1)
def GetRawJumpTarget(ea):
if ea is None:
return None
insnlen = GetInsnLen(ea)
if not insnlen:
return None
result = MakeSigned(idc.get_wide_dword(ea + insnlen - 4), 32) + ea + insnlen
if ida_ida.cvar.inf.min_ea <= result < ida_ida.cvar.inf.max_ea:
return result
return None

2 bit branch predictor with two for loops

I got a 2 bit branch predictor, my starting state is weakly taken and I need to calculate the prediction accuracy:
for (int i=0; i < 100; i++)
{
for (int j=0; j < 50; j++)
{
...
}
}
So with i = 0 we take the branch, so we are at i = 0 and j = 0 and set our predictor to strongly taken, right ? So if we iterate j now, does that mean we are not taking a new branch ? As we are still in the i = 0 branch, or does every iteration count as a new branch ?
Let's manually compile it into x86 assembly first for better understanding (any other would do to):
mov ebx, 0 // this is our var i
.L0:
# /------------ inner loop start -----------\
mov eax, 0 // this is our var j
.L1:
// ...
add eax, 1
cmp eax, 50
jl .L1 // jump one
# \------------ inner loop end -------------/
add ebx, 1
cmp ebx, 100
jl .L0 // jump two
I think this code is pretty straight forward even if your not familiar with assembly:
Set ebx to 0
jump two gets back here
Set eax to 0
jump one gets back here
Execute our loop code // ...
add 1 to eax
compare eax to 50 (this sets some bits in a flag register)
jump to label .L1: if eax wasn't 50
add 1 to ebx
compare ebx to 50 (this sets some bits in a flag register)
jump to label .L0: if ebx wasn't 100
End of the loops
So on the first iteration we arrive at jump one and predict it will be taken. Since eax < 50 we take it and update it to strongly taken. Now we do this another 48 times. On the 50 iteration we don't jump because eax == 50. This is a single misprediction and we update to weakly taken.
Now we arrive at jump two for the first time. since ebx < 100 we take it and update it to strongly taken. Now we start all over with that inner loop by jumping to L0. We do this another 98 times. On the 100 iteration of the inner loop we don't jump because ebx == 100. This is a single misprediction and we update to weakly taken.
So we execute the innerloop 100 times with a single misprediction each for a total of 100 mispredictions for jump one and 100 * 49 = 4900 correct predictions. The outer loop is executed only once and has only 1 misprediction and 99 correct predictions.

windbg script causes memory access violation

I am using the following windbg script to break when a certain value is encountered in the buffer when reading a file
bp ReadFile
.while(1)
{
g
$$ Get parameters of ReadFile()
r $t0 = dwo(esp+4)
r $t1 = dwo(esp+8)
r $t2 = dwo(esp+0x0c)
$$ Execute until return is reached
pt
$$ Read magic value in the buffer
$$ CHANGE position in buffer here
r $t5 = dwo(#$t1+0x00)
$$ Check if magic value matches
$$ CHANGE constant here
.if(#$t5 == 0x70170000)
{
$$db #$t1
$$ break
.break
}
}
$$ Clear BP for ReadFile (assume it is the 0th one)
bc 0
I get the following memory access violation when I run this script.
Memory access error at ');; $$ Check if magic value matches; $$ CHANGE constant here; .if(#$t5 == 0x70170000); {; $$db #$t1;; $$ break; .break; };'
Why is this the case?
If you need to read the buffer contents at kernel32!ReadFile you need to save the buffer address and step out of the function using gu (goup or step out)
when broken on ReadFile esp+8 points to the buffer so save it and step out
r $t1 = poi(#esp+8);gu
the first Dword of the buffer is poi(#$t1) compare it with the required Dword
and take necessary action with .if .else
.if( poi(#$t1) != 636c6163 ) {gc} .else {db #$t1 l10;gc}
putting this all together in one line the script shoule be
bp k*32!ReadFile "r $t1 =poi(#esp+8);gu;.if((poi(#$t1))!=636c6163){gc}.else{db #$t1 l10;gc}"
here 636c6163 is 'clac' (calc reversed ) use the dword you want instead of this
a sample run on calc.exe xp sp3 32 bits
bl
bp k*32!ReadFile "r $t1=poi(#esp+8);gu;.if((poi(#$t1))!=636c6163){gc}.else{db #$t1 l10;gc}"
.bpcmds
bp0 0x7c801812 "r $t1 = poi(#esp+8);gu;.if( (poi(#$t1))!=636c6163){gc}.else{db #$t1 l10;gc}"
0:002> g
00b865b0 63 61 6c 63 5f 77 68 61-74 69 73 5f 69 6e 74 72 calc_whatis_intr
00374df0 63 61 6c 63 00 ab ab ab-ab ab ab ab ab fe ee fe calc............

Read a sector to address zero

%include "init.inc"
[org 0x0]
[bits 16]
jmp 0x07C0:start_boot
start_boot:
mov ax, cs
mov ds, ax
mov es, ax
load_setup:
mov ax, SETUP_SEG
mov es, ax
xor bx, bx
mov ah, 2 ; copy data to es:bx from disk.
mov al, 1 ; read a sector.
mov ch, 0 ; cylinder 0
mov cl, 2 ; read data since sector 2.
mov dh, 0 ; Head = 0
mov dl, 0 ; Drive = 0
int 0x13 ; BIOS call.
jc load_setup
lea si, [msg_load_setup]
call print
jmp $
print:
print_beg:
mov ax, 0xB800
mov es, ax
xor di, di
print_msg:
mov al, byte [si]
mov byte [es:di], al
or al, al
jz print_end
inc di
mov byte [es:di], BG_TEXT_COLOR
inc di
inc si
jmp print_msg
print_end:
ret
msg_load_setup db "Loading setup.bin was completed." , 0
times 510-($-$$) db 0
dw 0xAA55
I want to load setup.bin to memory address zero. So, I input 0 value to es register (SETUP_SEG = 0). bx, too. But it didn't work. then, I have a question about this issue. My test is below.
SETUP_SEG's value
0x0000 : fail
0x0010 : success
0x0020 : fail
0x0030 : fail
0x0040 : fail
0x0050 : success
I can't understand why this situation was happened. All test was carried out on VMware. Does anyone have an idea ?
I'm not sure if this is your problem, but your trying to load setup.bin in the Real Mode IVT (Interrupt Vector Table). The IVT contains the location of each interrupt, so I'm assuming that your boatloader is overwriting them when it loads setup.bin into memory! Interrupts can be sneaky and tricky, since they can be called even if you didn't call them. Any interrupt vector you overwrote will likely cause undefined behavior when called, which will cause some problems.
I suggest setting SETUP_SEG to a higher number like 0x2000 or 0x3000, but the lowest you could safely go is 0x07E0. The Osdev Wiki and Wikipedia have some helpful information on conventional memory and memory mapping.
I hope this helps!

Analyzing binary taken from memory dump in IDA Pro

I'm having problems with analyzing a simple binary in IDA Pro.
When running a program, i dumped part of its memory (for example, unpacked code section in the memory) into a file, using WinDbg.
I would like to analyze it using IDA, but when trying to just load the binary - it will only show its raw data.
Of course the binary is not a full PE file, so I'm not expecting a deep analysis, just a nicer way to read the disassembly.
So the question is - How can i make IDA disassemble the binary?
Thanks! :)
select an appropriate address and press c
that is MakeCode(Ea); ida will convert the raw bytes to code and disassemble it
pasted below is a simple automation with an idc script but idas automation is imho subpar so you should stick with manual pressing of C in user interface
:dir /b
foo.dmp
foo.idc
:xxd foo.dmp
0000000: 6a10 6830 b780 7ce8 d86d ffff 8365 fc00 j.h0..|..m...e..
0000010: 64a1 1800 0000 8945 e081 7810 001e 0000 d......E..x.....
0000020: 750f 803d 0850 887c 0075 06ff 15f8 1280 u..=.P.|.u......
0000030: 7cff 750c ff55 0850 e8c9 0900 00 |.u..U.P.....
:type foo.idc
#include <idc.idc>
static main (void) {
auto len,temp,fhand;
len = -1; temp = 0;
while (temp < 0x3d && len != 0 ) {
len = MakeCode(temp);
temp = temp+len;
}
fhand = fopen("foo.asm","wb");
GenerateFile(OFILE_LST,fhand,0,0x3d,0x1F);
fclose(fhand);
Wait();
Exit(0);
}
:f:\IDA_FRE_5\idag.exe -c -B -S.\foo.idc foo.dmp
:head -n 30 foo.asm | tail
seg000:00000000 ; Segment type: Pure code
seg000:00000000 seg000 segment byte public 'CODE' use32
seg000:00000000 assume cs:seg000
seg000:00000000 assume es:nothing, ss:nothing, ds:nothing, fs:no thing, gs:nothing
seg000:00000000 push 10h
seg000:00000002 push 7C80B730h
seg000:00000007 call near ptr 0FFFF6DE4h
seg000:0000000C and dword ptr [ebp-4], 0
with windbg you can get the disassembly right from command line like this
:cdb -c ".dvalloc /b 60000000 2000;.readmem foo.dmp 60001000 l?0n61;u 60001000 60001040;q" calc
0:000> cdb: Reading initial command '.dvalloc /b 60000000 2000;.readmem foo.dmp 60001000 l?0n61;u 60001000 60001040;q'
Allocated 2000 bytes starting at 60000000
Reading 3d bytes.
60001000 6a10 push 10h
60001002 6830b7807c push offset kernel32!`string'+0x88 (7c80b730)
60001007 e8d86dffff call 5fff7de4
6000100c 8365fc00 and dword ptr [ebp-4],0
60001010 64a118000000 mov eax,dword ptr fs:[00000018h]
60001016 8945e0 mov dword ptr [ebp-20h],eax
60001019 817810001e0000 cmp dword ptr [eax+10h],1E00h
60001020 750f jne 60001031
60001022 803d0850887c00 cmp byte ptr [kernel32!BaseRunningInServerProcess (7c885008)],0
60001029 7506 jne 60001031
6000102b ff15f812807c call dword ptr [kernel32!_imp__CsrNewThread (7c8012f8)]
60001031 ff750c push dword ptr [ebp+0Ch]
60001034 ff5508 call dword ptr [ebp+8]
60001037 50 push eax
60001038 e8c9090000 call 60001a06
6000103d 0000 add byte ptr [eax],al
6000103f 0000 add byte ptr [eax],al
quit:
ollydbg 1.10 view-> file-> (mask any file) -> foo.dmp -> rightclick -> disassemble