PDA

View Full Version : Conditional Branch Logger A New Plugin


blabberer
June 13th, 2007, 01:50
Hello OllyDbg users,

We, Kayaker, dELTA and Me take the pleasure of Announcing a new plugin:

Conditional Branch Logger

The salient features of the plugin are as follows:

* An ability to detect all conditional branches and log their behaviour during
runtime without having to single step the whole process, which results in a dramatic improvement of performance when compared to run trace logging.

* An ability to choose specific conditional jumps only to monitor and log.

* Log conditional branches spanning multiple modules .

* an ability to filter out sytem modules from being logged

* Ability to choose and opt included ranges and excluded ranges to fine
tune the logging.

* Ability to disable, delete and restore the logging status of the
detected conditional branches.

* An ability to list all the procs that ollydbg has recognised, with
their names if they exist, as a handy referance so that it is easier to
include or exclude ranges.

* A text mode log file that could serve to compare two similar runs to detect divergent paths taken with respect to input


* A runtime log window that displays the status of conditional branches live with context menus to edit, delete and disable the entries on the fly.

* Context menus in memory window to mass add modules after auto
analysing them or add specific modules.

* Context menus in memory window to add non module ranges.

* Context menu to add odd ranges in disassembly window.

* And a few more, like background tasks e.g. saving the entire database of conditional branches to udd and restored back when restarting the project afresh.

We hope this plugin could be of immense use when monitoring execution flow path.


Any comments, bouquets and brickbats are welcome.


Please direct your suggestions, criticisms, bug reports

to ollydbg plugin sections.


I personally would like to offer my thanks to dELTA and Kayaker for
their initiative to bring this plugin to a successful release.
I thank Woodmann for hosting this OllyDbg specific forum,
and of course all of you OllyDbg users and well wishers.

The plugin's genesis can be found in this thread:

http://www.woodmann.com/forum/showthread.php?t=9807


From the simple 40 line prototype with which i seeded this plugin, I'm
really glad to see this Conditional Branch Logger evolve into a
multi-language, multi-kilobyte, mature plugin for OllyDbg.

I'm also very glad to have the pleasure of working along with Kayaker,
and dELTA.

dELTA is instrumental in providing the fast logging engine, the
configuration save and restore code, and the GUI frontend (including
modifying it umpteen times to match the requests ).


Kayaker is the Chief Architect of the entire code that interfaces with the GUI and OllyDbg.


I am proud to be the Catalyst, Consultant and Progenitor of the idea that started this all.

You can find this plugin at OllyStuph

http://www.woodmann.com/collaborative/tools/Conditional_Branch_Logger


Thanks and Regards,

blabberer

gera
June 13th, 2007, 07:56
does it make use of the MSR registers to do branch tracing and logging on newer processors? or it disassembles and sets breakpoints? or something else?

thanks for the plugin, I foresee millions of uses for it!

gera
June 13th, 2007, 07:57
I answer myself: I just read the original thread, and apparently it does use the msr registers and stuff.

TQN
June 13th, 2007, 11:48
Excellent plugin, blabberer, Delta and Kayaker !
I am playing with your plugin, and I think I found 2 bug:
- When I start OllyDbg from shortcut or Context menu in Explorer, the cbl_gui.dll could not load. I read your source code and found the bug in the function ODBG_Plugininit, at the line which calls GetCurrentDirectory. In my opinion, do not use this function, replace it with GetModuleFileName(NULL,...) to get OllyDbg.exe, .ini, plugin path.
- OllyDbg shows the warning message box "Suspicious breakpoint...." many times when the Conditional Branch Logger show the wait box "Please wait while conditional branch logger is processing...", and I must press Enter key many times. So I have to kill OllyDbg with Process Explorer.
Hope you will fix those bugs.
Best regards, and thanks very much for your greate plugin, great source code !
TQN

Kayaker
June 13th, 2007, 18:07
Hi

Thank you for the feedback.

No, the plugin doesn't use MSR registers it's based only on what Olly disassembles as conditional branch instructions, the JCC series, JCXZ/JECXZ and LOOP instructions if selected. That might be something to look into though if the idea could be incorporated with regular OllyDbg functioning.

Re the "Suspicious breakpoint" message, that's a message from Olly itself. I think there are two situations where that might occur. One is if you add a logging (included) range of a non-standard section or memory mapping, such as the PE header, data section, non-executable heap location, etc. Certain bytes could be interpreted as conditional jump instructions by Olly and when it tries to set a breakpoint there you get the warning.

The other situation where that might occur is if the module hasn't been analyzed yet by the Olly code analysis function. In the majority of cases the plugin will first test if the module has been analyzed by checking the t_module->codedec flag, if not it will analyze the module first using Olly's Analysecode function (or you can do it from a separate menu item) before adding anything as a logging range.

In most cases you *shouldn't* get the "Suspicious breakpoint" message if the addresses are valid code in the first place. It's actually a warning that one needs to be judicious in selecting ranges to log with the plugin (the plugin will warn you if you try to add non-standard regions from the Ollydbg Memory map window at least). I've been caught several times as well and had to close possibly hundreds of message boxes. I wish there was a way to tell Olly to either ignore the problem or just stop processing. Since chances are that the breakpoint will never be hit, it wouldn't do any harm to have a false breakpoint set and it's more of annoyance (at least to our plugin ) than anything else.


As for the issue of cbl_gui.dll not loading, I wasn't able to reproduce that error even when opening Olly from a shortcut, context menu or run command. My assumption is that GetCurrentDirectory should retrieve the location of the currently running Olly exe process, the plugin then parses ollydbg.ini (in the same directory) to get the plugin path and tries to load the dll from there. If that fails it will try to load it from the main Olly directory or %PATH% locations. I'm certainly willing to change the code if there's a problem.

Thanks again, all reports are welcome.

Regards,
Kayaker

TQN
June 13th, 2007, 20:21
Thanks for your reply, Kayaker !
At this time, I have to copy cbl_gui.dll to System32 directory. And if we have a new version, I should remember that I have to copy new cbl_gui.dll to System32 directory, overwrite the old dll. It is inconvenient.
And with a lot of modified OllyDbg version, your plugin will not work because the ollydbg.ini will not found. So I think we can change the code as below:
Code:

....
char szPluginPath[_MAX_PATH] = { 0 };
char szPluginDrive[_MAX_DRIVE] = { 0 };
char szPluginDir[_MAX_DIR] = { 0 };
....
GetModuleFileName(hinst, szPluginPath, MAX_PATH);
splitpaht(szPluginPath, szPluginDrive, szPluginDir, NULL, NULL);
makepath(szPluginPath, szPluginDrive, szPluginDir, "cbl_gui", ".dll";
if (0 != _access(szPluginPath, 0))
{
// Error: file cbl_gui.dll not existed
....
}
else
{
guidll = LoadLibrary(szOllyPluginPath);
}
....

With this code, we can place the cbl_gui.dll to OllyDbg's Plugin directory, and we can alway load the dll.
If I have any mistake, forgive me.
Best regards,
TQN

Kayaker
June 13th, 2007, 21:54
Quote:
[Originally Posted by TQN;66363]And with a lot of modified OllyDbg version, your plugin will not work because the ollydbg.ini will not found.


Thanks TQN, I can look into the changes you suggest. I've not used any modified Olly versions so don't know what effects that may have.

One question though, will the cbl_gui.dll not load if you place it in the Olly main directory? This is the default location, should it not be found in the plugin directory. That should be just as reliable as placing it in the windows or windows/system32 directory (%PATH%)

Like most dll's, the command
LoadLibrary("cbl_gui.dll";
should first search the current process directory and then %PATH% for the dll in question. So I'd be very surprised if the dll didn't load from the main Olly directory at least. I certainly don't *want* the dll having to be placed in the windows directory, nothing I hate more than scattered program files.

Cheers,
Kayaker

TQN
June 13th, 2007, 22:25
Thanks Kayaker !
I moved the cbl_gui.dll to OllyDbg directory, and it works. But, because many plugins requires and places its additional dll to OllyDbg directory, for example: RL!Weasle with dumper.dll, importer.dll, realign.dll, OllyBone with ollybone.sys..., so we will have many files in OllyDbg directory. And after, if we have a new version of some plugin, we have to extract some files to OllyDbg plugin dir, some files to OllyDbg main directory, and if we need copy some plugin to another machine, we have to remember and copy some dll from OllyDbg main directory. So, why we can not place all of dll in the OllyDbg directory ?
Thanks you a lot for waste your time to answer my post !
Best regards,
TQN

Sirmabus
June 14th, 2007, 01:53
Cool,

Take a look at the thread over here:
http://www.openrce.org/blog/view/535/Branch_Tracing_with_Intel_MSR_Registers

If you turn on the BTF flag your tool would run much faster, BUT not sure how it would work in Olly since it expects the default step behavior.

blabberer
June 14th, 2007, 03:29
hi all,

thanks for the great feedback

putting the cbl_gui to ollydbg directory should get the cbl_gui in search path

yeah i too hate to have the the files scattered at umpteen places
i wish ollydbg had a Plugingetvalue(val_pluginpath) which i could have gladly used other than that only reliable option seemed to be asking the user for a path to cbl_gui and taking it from the user which is equally annoying

and as to version changes even if i had a hardcoded path from user i probably would need a version check as well to confirm if the gui dll is the same with which plugin is interfacing

thanks TQN for suggestions and code hopefully it should be eliminated

as to supicious breakpoint i at one time clocked a million breakpoints
but the app wasnt any antidebugged one plain ms winword.exe
i didnt get any suspicious breakpoint message

it only happens if the addrerss space isnt analysed or it is non executable memory

could you get more details about the app in question
if it is non commercial toy then a link would be appreciated too

ill see if i can bypass the suspicious thingies

dELTA
June 14th, 2007, 08:03
Quote:
[Originally Posted by blabberer;66343]I am proud to be the Catalyst, Consultant and Progenitor of the idea that started this all.
Hehe, don't be so modest, you did a lot more than that.

And me for one couldn't resist the idea of working together with the inofficial #1 OllyDbg guru on a plugin project.

Nice to see the feedback from people too. The MSR register thingy definitely sounds like an interesting possibility, even though a bunch of obstacles regarding the Olly integration with this might have to be solved first.

Please keep the feedback coming, and stay tuned for a very exciting already planned feature upgrade in the future too...

blurcode
June 14th, 2007, 12:18
This is very good plugin, can you please post the delphi source for the gui part too?

Maximus
June 14th, 2007, 14:08
Quote:
[Originally Posted by dELTA;66390]The MSR register thingy definitely sounds like an interesting possibility, even though a bunch of obstacles regarding the Olly integration with this might have to be solved first.


Which ones? What problem have you had using them?

dELTA
June 16th, 2007, 14:22
Quote:
[Originally Posted by blurcode;66403]This is very good plugin, can you please post the delphi source for the gui part too?
Sorry, it contains commercial components and code, so that cannot be done at the moment.

Quote:
[Originally Posted by Maximus]Which ones? What problem have you had using them?
I was mostly thinking about the problems that could occur if Olly does not support this register functionality directly (which I'm not sure of), and that we in that case might have to implement (parts of) the debugger code/loop ourselves for such a thing, which would make the thing much more detached from OllyDbg. Just a theory though, and at the moment I don't know enough about several things to say it really is so. Please let us know about any additional thought you may have about this.

Maximus
June 16th, 2007, 19:56
mmh.. not sure I understand how the plugin works, however a very simple driver with a service call that sets the MSR (wait I get the number from manual) 1d9h, msr_debuctl_a.
set ther BTF==1 and you will single-step on branches only. on every debug event (i suppose a in olly plugin has a function that can be called whenever a debug exception happens?), call the driver service so it gets set==1 again.

Or are you meaning the branch trace cache the P4 has?

gera
June 17th, 2007, 10:28
Quote:
[Originally Posted by dELTA;66441]

I was mostly thinking about the problems that could occur if Olly does not support this register functionality directly (which I'm not sure of),


To use the branch logging and tracing features, the first thing you have to do is turn it on using the MSR 0x1d9. This is a global flag (I would guess per core), so it will turn the feature on for every process in the system (per core).

Then, you only have to deal with SINGLE STEP (eflag 0x100), and all the code is the same as for handling the single step trap normally, except that to get the addresses of where the branch was and where it branched to, you need to use some other MSR registers, as explained in the manual:

Quote:
You will see two interesting registers "LastBranchFromIP" (0x1DB) and "LastBranchToIP" (0x1DC).


here's some python code to set the register, I guess you can get how to do it in C from this code:

Code:

SysDbgReadMsr = 16
SysDbgWriteMsr = 17

ULONG = c_ulong
ULONGLONG = c_ulonglong

class SYSDBG_MSR(Structure):
_fields_ = [
("Address", ULONG),
("Data", ULONGLONG),
]

def write_msr():
msr = SYSDBG_MSR()
msr.Address = 0x1D9
msr.Data = 2
status = windll.ntdll.NtSystemDebugControl(SysDbgWriteMsr,
byref(msr),
sizeof(SYSDBG_MSR),
0,
0,
0);



this code (and the info on this post) was taken from practice and mainly for a post on Pedram Amini's blog at http://www.openrce.org/blog/view/535/Branch_Tracing_with_Intel_MSR_Registers.

I think you should at least give it a try, it would improve the performance of the plugin like crazy (I guess)... Then, there's another very interesting article on how to improve the performance of tracers, but I can't find it now. I'll look it up latter

Maximus
June 17th, 2007, 11:55
pretty nice ntdll function

edit-----

has anyone fully implemented the trace buffer of P4 on a workable basis? It is very interesting, but I missed a bit the way memory is allocated/used.

Kayaker
June 18th, 2007, 01:16
Interesting ideas all. It seems that the real benefit of enabling MSR tracing, over Process Stalkers method of grouping instructions into "basic blocks" delineated by branch instructions (call, jump, etc.), or our plugins method of setting breakpoints on conditional branch instructions, is that it's not dependant on first having a recognizable disassembly.

From the sounds of it, the BTF (single-step on branches) flag (bit 1) would be activated *runtime*, so in other words even encrypted branch instructions deep in the code would be logged as they are executed, even if the rest of the world can't tell they are there from a disassembly.

I can't really see that there would be much of a speed increase per se however, since neither Process Stalker nor our plugin are doing a full run trace. Non-branch instructions are simply ignored in all cases.


Sirmabus quoted the intel docs:

Page 329, vol 2, shows us what "control transfers" trigger this single step exception to fire:
"
* JMP, CALL, RET
* Jcc, JrCXZ, LOOPcc
* JMPF, CALLF, RETF
* INTn, INT 3, INTO, ICEBP
* Exceptions, IRET
* SYSCALL, SYSRET, SYSENTER, SYSEXIT
* INTR, NMI, SMI, RSM

I wonder if the JMP and CALL transfers include the indirect register based ones as well? I suppose there's no reason they shouldn't.

One of the things I didn't like from the OpenRCE thread, it sounds like you can't develop this MSR stuff under VMWare..
It certainly has interesting potential though.


As for our CBL plugin, right now it logs the standard conditional branch instructions, but it could easily be extended to include indirect register based branch instructions as well (CALL[EBP+xxx], JMP EAX,..) and log the destination. This is under development actually and is planned for a future version. Other instructions such as RET or even regular direct CALL/JMP instructions could also be added if there seemed to be any use for that.

Kayaker

gera
June 18th, 2007, 10:01
sure the BTF includes the indirect jmp/calls and all other branches (push+ret).

an indirect speed gain is that you don't have to disassemble after every breakpoint to find the next branch (if you don't disassemble on the go, you get lost on offuscated/encrypted code). I guess you are seeting a breakpoint on the next branch, single stepping through it to know where it goes, and then disassembling until the next branch and setting a breakpoint there. I bet that consumes time.

Anyway, for a faster approach, please take a look at the excelent paper by nergal (Rafal Wojtczuk) at http://www.avertlabs.com/research/blog/?p=140. He describes an interesting (and way faster) method of doing in-process tracing.

(this is the other article I was refering to earlier)

blabberer
June 18th, 2007, 11:06
yes i was aware of pedram aminis msr_debug_ctla branch tracing blog post

in fact when this plugin was in its poc form (like in that thread i had run a comparison with pydbg tracer output )
Code:

ollydbg output
==========================================================

7C901230 Attached process paused at ntdll.DbgBreakPoint
Thread 00000EB0 terminated, exit code 0
01006127 Breakpoint at calc.01006127
Jump Not Taken
0100612D Breakpoint at calc.0100612D
Jump Not Taken
01006136 Breakpoint at calc.01006136
Jump Taken
0100613F Breakpoint at calc.0100613F
Jump Taken
01006148 Breakpoint at calc.01006148
Jump Taken
01006151 Breakpoint at calc.01006151
Jump Not Taken
01006156 Breakpoint at calc.01006156
Jump Not Taken
010063EB Breakpoint at calc.010063EB <- i placed hard break here
=====================================================



tracer output
====================================================

initial breakpoint hit at 7c90e027: retn 0x14

putting all threads into single step mode

calc.exe 01000000 -> 0101f000
3796 -> setting single step
1692 -> setting single step
bp: 01006118: push ebp <--- extra
ss: 01006119: mov ebp,esp
ss: 0100611b: sub esp,0x10
ss: 0100611e: push ebx
ss: 0100611f: push esi
ss: 01006120: push edi
ss: 01006121: mov edi,[ebp+0xc]
ss: 01006124: cmp edi,0x7b
ss: 01006127: ja 0x10063cd <--
ss: 0100612d: jz 0x1006336 <--
ss: 01006133: cmp edi,0x5
ss: 01006136: jz 0x100628d <--
ss: 0100613c: cmp edi,0x10
ss: 0100613f: jz 0x100623f <--
ss: 01006145: cmp edi,0x1a
ss: 01006148: jz 0x1006207 <--
ss: 0100614e: cmp edi,0x4e
ss: 01006151: jz 0x1006177 <--
ss: 01006153: cmp edi,0x53
ss: 01006156: jnz 0x10063eb <--
ss: 010063eb: push [ebp+0x14] <--
ss: 010063ee: push [ebp+0x10]
ss: 010063f1: push edi
ss: 010063f2: push [ebp+0x8]
ss: 010063f5: call [0x10010d4]
bp: 010063fb: jmp 0x1006523 <-- extra
ss: 01006523: pop edi
ss: 01006524: pop esi
ss: 01006525: pop ebx
ss: 01006526: leave
ss: 01006527: retn 0x10


i happened to notice it was logging too much and im not much of a scripter or python geek

anyway i looked around then to see if bts could be told to log specific branches and it didnt look like there were any methods to make it log only specific branches

also it didnt look like if it could be logged across whole of process space
while with this plugin you can trim cut and choose different strategies and
variations

yes btf has one extra ability to get you obfuscated self modifying connditional branches but with that it also gets you a baggage of plain unconditional jumps as well which this plugin plainly ignores

no this plugin doesnt do any dynamic tracing/disassembling on the fly at the moment to see if any self modified conditional jumps have been created as of yet though a scanner could be implemented

infact any self respecting checksummed code may simply fail with preset break points (a positive side effect is you can pinpoint/get closer to the last failed jump ) and possibly take counter measures as delete disable set bp after successfully evading checksum

yes i am also aware of umss technique (i think i saw it in mcafees page or matasanos blog and i posted a link here some time ago)

thanks for the feedbacks and ideas hopefully ill try to patch together a btf as well in near future

till then keep the feed back coming

i would actually love to see this plugin used and problems reported back so that it could be further improved

regards

Sirmabus
June 18th, 2007, 17:24
Cool,

I've been playing around with BTF thing. Making a stand alone tool, not in a "debugger" per say.

While I can get it to run well in a little test bed with a few simple threads,
it will crash often if say the thread belongs to a message pump, etc.
Looks like some sort of stack problem(s), when trying to step though some API calls. I've tried to detect this and handle it (by turning off step inside module, with a software BP on return) but it's not 100%..

Also it's not so generic. And I've got to make a detailed processor system to identify what processor it's being run on and account for the differences in the MSR register use. Like AMD doesn't have a record stack, but Intel does.

It's kind of fun to mess with, and shows a lot of promise if the problems could be worked out. It's defiantly faster since it's just triggering on branches.

I'm starting to think, the best bet will be to use a kernel driver that hooks in layer just above where the exceptions are dispatched to user land.
That way they are outside the targets space to avoid issues inside, and should be faster with out the overhead.
It will just take some sort of shared memory/ring buffer to get the trace info out..

If I come up with something useful, I'll share it here.

blabberer
June 19th, 2007, 02:20
Quote:
sirmabus
it will crash often if say the thread belongs to a message pump, etc


this is exactly what i was having in mind

wit this plugin you can simply land in the pertinent msgpump without any problem

lets do a simple calc.exe msg pump

open calc.exe in ollydbg
plugins -> cbl-> configure-> ok

you will see 1031 conditional jumps processed in 129 microseconds
hit f9 (run)
and wait till calc.exe pops up a few seconds at max
hit f12 (pause)
hit the CBL toolbar button -> right click -> delete entries executed
f9 (run again)

hover your mouse over calc.exe

you can find where WM_MOUSEMOVE is HANDLED in the msgpump

not interested in MOUSEMOVE simply delete executed entries again

now hit a button say 7 the log will show what jumps were taken and what not
and by inferring you have hit the handler for BM_CLICK
and so on


yes playing with msr is good for one machine poc
but the registers are arcane and vary a lot with each processor,stepping and model, and it is hell to read and understand the footnotes asterisks and similar caveats that accompany each MSR (oh btw a simple script on windbg
could land you what msr are available in your processor and what do they hold at the moment you read the msr can be got like follows)

start -> cmd -> kd -kl
.logopen c:\rdmsrlog.txt
r $t0 = 0
.while ($t0 < 0xc100) { rdmsr $t0; r $t0 = $t0+1}

you may ask why 0xc100 if thats too much time take your pick make it 0x300

or get the manual and do .if ($t0<210 && $t0 > 200) {rdmsr ........;}

a conditional log based on intel manual appendix b msr's

if you notice system programming manual appendix B MSR Registers you can see 0xc000:some thing register is defined as well


for example in my p3 i can read the LBR_LAST_RECORD[0] in msr 0x1dbh
while in p4 or p6 (DebugctlMsr) these have been shifted to MSR 0x6B0
its pretty arcane to make this as generic as possible

while this plugin doesnt have to deal with arcaneness because it does it in the conventional way

Sirmabus
June 22nd, 2007, 00:44
I think we are thinking a lot along the same lines. Some type of divide and conquer approach to finding some things in code, etc.

It turns out, I think the stack problem could have been an overflow (a bug). As I needed to call at least for testing, "IsBadReadPtr()" type functions.
Hopefully I can just pass on the exception (access violations) and it will unwind it's self, or I'll make my own custom IsBadxxxxPtr() functions.

On the kernel side, it looks like one would want to hook "KiDispatchException()" some place and handle the single step (with, or with out branch step) right there.
The exception would never enter user mode.
Maybe it's not needed but:
1. Faster with out the overhead (maybe the overhead of passing the context around is not so bad).
2. User mode spaces don't need, nor won't F'k with the single step exception.
3. Might have too to grab the MSR recorded value in sequence before an other thread fire off and changes it. For that matter, this might have to be in the HAL or where interrupts are handled in the kernel.

I think the branch trace processor differences could be worked out. It looks like most if not all newer processors have the BTF feature.
Got to classify them and read the CUPID and MSR feature values/bits, etc.

Fun stuff..

blabberer
June 22nd, 2007, 01:40
well on modern processors where btm is available and CPL qualifier flag is available

you can tell it to skip all R0 jumps,calls,ints,and exception
and only log r3 with FLAG_USR enabled

also if you set up a DS:SAVE area (a page marked dirty and also global so that it is accessible on all cr3 changes see setting up DS:Save area and DS:SAVE AREA pointer setup
all you need to do it seems is to leech the stuff when the buffer is full and it has opened an Exeption the sytem uses that buffer when you have set both btf and tr in the exception handler it seems not sure exactly but thats what i infer from the intel manuals

also the methods in theory looks like a fully documented procedure that doesnt need any hooks and hacks of any kind of Dispatchers

just create a poc in one of the latest and greatest processors and then the extremes could be tackled later
or simply can pass a message you need cpuid:eax = # result edx:bit ## enabled for my app to work
get an new processor or shift delete this

Sirmabus
June 22nd, 2007, 20:00
Yea, I was thinking of those things too. The buffered thing should be even better performance wise.
Although not so sure, while information is sparse, there is some indication that the processors do some odd things for these features to work (like dumping the code cache on every instruction).
Ultimately would be nice to have a system that would use the best the processor has to offer. Like the buffered trace thing if supported, or just the BTF flag exception as it seems to have wider support (on AMDs too, etc).

Also, despite what I said earlier, I don't think there are thread problems per say. Because looking at the kernel code (in IDA), it looks like all threads in a user process are suspended while an exception is handled.

It turns out, it doesn't appear to be a bug in my stuff.
It's just certain spots in system modules (kernel32.dll, ntddl.dll) cause some sort of stack corruption.
Looks like mostly in the LPC message stuff (in ntddl.dll), where the OS IPC msg's are handled. I don't know where exactly yet, but I can assume it's something to do with trying to trace the same code that's receiving the single step messages and causing some sort of deadly recursion.

Hence, I think it's better to use some sort of kernel driver to operate completely out of the user mode space. The user process will not even know it's being single stepped; unless it looked at the trap flag (if there was a reason this could be hidden).
Another host/front-end process will control the attach/loading, and it will just grab the info it needs from the mapped memory (perhaps using some sort of fast queue like a ring buffer), or from the driver directly.

Time to fire up the driver stuff and install a VM.

Wouldn't a free real time tracing solution be great?

Sirmabus
July 24th, 2007, 23:59
Update:
Got a basic branch tracing setup using a KMD with a simple hook/intercept of hardware int1.

Works so well, I can even trace complex processes like PC video games (with many threads) in real time. Slows things down a lot, but still workable.
Try that using debugging APIs..

Working well on a P4, or AMD64. Next thing is try using the branch store buffer (available only on Intel CPUs) to hopefully get less of a performance hit.

dELTA
July 25th, 2007, 16:29
Sounds really nice Sirmabus! Any chance of you sharing the source of this wonderful contraption?

dELTA
February 15th, 2008, 16:44
For reference, first of all, the cool tool that Sirmabus mentions above just turned up again, in the following thread:

http://www.woodmann.com/forum/showthread.php?t=11306


Also, since the OllyStuph area has now moved into the larger Collaborative RCE Tool Library (CRCETL), here below is a link to the new home of the Conditional Branch Logger plugin, for anyone looking for it:

http://www.woodmann.com/collaborative/tools/Conditional_Branch_Logger


Darkelf
May 3rd, 2008, 06:04
Hi there,

after a break due to RL-issues I'm happily back in RCE. When I found this plugin, I bounced up and down like a little kid . Simply to good to be true.
Unfortunately, whenever I want to use, the same error occurs. The breakpoints are set, I let the program run and an ugly messagebox comes up:

"Breakpoint corrupted!
OllyDbg set byte at address 00xxxxxx to CC (code of comand INT3, used as breakpoint). Now this byte contains FB. Do you want to keep modified command? (If you answer 'No', old code 74 will be restored)."

Sometimes it says "FA" instead of "FB". This happens with whatever program I try to use CBL on. If I click "Yes" in the messagebox, the box simply stays, if I click "No", it goes on to the next breakpoint, showing the next messagebox. No way to get out of Olly since these are modal messageboxes.
Am I doing something wrong here?

Any help is highly appreciated.
Thanks a lot in advance.

Best regards
darkelf

blabberer
May 3rd, 2008, 12:06
that messagebox is emitted by ollydbg when it finds the code has been modified
especially when debugging self modifying programs

before setting breakpoints ollydbg records the original byte which it is going to replace by int 3
when we disable or remove the breakpoint it replaces the original byte back

but before replacing it checks transparently if the byte is still the same
if it is not same it emits that messagebox

since you say it happens in every exe that you are trying to debug
this scenerio doesnt seem to be the case

what other plugins are you using at the same time
is there a possibility that one of the other plugins is interfering with this plugin

can you try reproducing this problem with a virgin unzipped ollydbg in a new folder and only
this plugin and one simple debuggee as target and confirm back
if it is still the case

mean while ill try and see if i can reproduce this in some weird conditions

thanks for the report

hope it is an interference only

Darkelf
May 3rd, 2008, 14:44
Hi and thanks for your reply,

I did as you said (used a virgin Olly) and it worked.
I then added all the plugins I use one by one - and it still worked!
Finally I recognized that my Olly (not the virgin one) was renamed to some random name. I changed that back to OLLYDBG.EXE and it worked also
That's cool but nevertheless strange, because renaming the virgin Olly to something else doesn't have any negative effect whatsoever. So I still can't tell you what's the cause for this. But I'm very happy that it works now.

Thank you very, very much for this amazing plugin.

Best regards
darkelf

blabberer
May 4th, 2008, 12:08
happy to hear that it works
i was wondering why should that happen at all
we've tried to keep that plugin's code as much legal as possible except for few hacks (for apis that werent documented
or had some deficiancies)

and we have tried to stress it by clocking a million breaks and still survive