Log in

View Full Version : IDA PRO Disassembly Window Manipulation


Aimless
March 9th, 2013, 15:24
Hello,

Too long in this business. Gotten used to seeing and doing things my way.

Most importantly, seeing code in ALL-CAPS. And with double spaced lines. Most of the time, that is.

I'm trying to write a plugin for IDA (anywhere 6.1 or upwards), that will automatically convert all lines in the disassembly in CAPITALS. And, double space the lines.

So, instead of:
------------
.text:0100739D push 70h
.text:0100739F push offset stru_1001898
.text:010073A4 call __SEH_prolog
.text:010073A9 xor ebx, ebx
-------snip


You get:
------------
.TEXT:0100739D PUSH 70H

.TEXT:0100739F PUSH OFFSET STRU_1001898

.TEXT:010073A4 CALL __SEH_PROLOG

.TEXT:010073A9 XOR EBX, EBX
-----snip

I don't mind wading though tons of documentation. But any kind soul willing to give me a pointer where exactly to begin? (No, not begin how to use the SDK, I mean, where to begin when you want to manipulate the display in the UI? And that too in the default disassembly window?). The IDA SDK documentation is not exactly...of a sterling quality.

And it's not something I can ask Ilfak or the hex-rays board (you know how it is).

Any suggestions please?

And I really don't mind doing this in IDAPython too, if you think that's going to be better and a more elegant solution.

Have Phun

mint77
March 9th, 2013, 18:46
I found this. It's from PBrennick.

Hope it helps.

Code:

mov edx, OFFSET String3 ; Point to the string
A0: mov al, byte ptr [edx] ; Get a character or next character
cmp al, 0 ; End of string?
je Display_String ; Go show it if yes
cmp al, 'A' ; Check for lower boundary
jb A1 ; Jump if not a letter
cmp al, 'Z' ; Uppercase?
ja A3 ; Go check for lower, if no
or al, 20h ; Convert to lowercase
mov byte ptr [edx], al ; Store it
A3: cmp al, 'w' ; Compare character for upper bounds, first check
jg A2 ; Jump if possible upper bounds error
cmp al, 'a' ; Check for lowercase
jb A1 ; Jump if not a letter
add al, 3 ; Otherwise add 3 to al
mov byte ptr [edx], al ; Store it
jmp A1 ; Done with this character
A2: cmp al, 'z' ; Compare character for upper bounds, second check
ja, A1 ; Jump if not a letter
sub al, 23 ; Otherwise do a wraparound
mov byte ptr [edx], al ; Store it
A1: inc edx ; Point to next character
jmp A0 ; Go get it
Display_String: ;

Kayaker
March 9th, 2013, 19:36
My first thought was to use a monospaced SMALL-CAPS font, but that wouldn't get you your empty lines and might look crappy and I couldn't find one to try anyway.

I'd take a look at MakeLine() and MakeNull() in lines.hpp, and their use in any out.cpp file in the sdk/module directory. Not sure if that quite fits the bill but probably a place to start.

disavowed
March 14th, 2013, 17:17
For capitalizing the mnemonics, you can patch \procs\pc.w32 - overwrite the lowercase mnemonics with their uppercase versions.

Aimless
March 14th, 2013, 17:35
Quote:
[Originally Posted by disavowed;94381]For capitalizing the mnemonics, you can patch \procs\pc.w32 - overwrite the lowercase mnemonics with their uppercase versions.


Ugh!

But that *does* seem like a good idea ATM.

Strange that you can build instrumentation inside IDA using the SDK and Python, but can't do something as easy as this...

Thanks Disa.

Have Phun

Aimless
March 14th, 2013, 19:57
Quote:
[Originally Posted by Kayaker;94372]My first thought was to use a monospaced SMALL-CAPS font, but that wouldn't get you your empty lines and might look crappy and I couldn't find one to try anyway.

I'd take a look at MakeLine() and MakeNull() in lines.hpp, and their use in any out.cpp file in the sdk/module directory. Not sure if that quite fits the bill but probably a place to start.


Yup. lines.hpp is definitely the way to go. Now, where the heck did I put that copy of Borland C++ .....


Thanks K.

Have Phun

Kayaker
March 16th, 2013, 15:14
I was playing with this to gain some experience in plugin writing. I've been able to produce capitalized disassembly text, but not as a direct replacement for the original. Producing CAPS is straightforward enough and can be placed in several different notification callbacks, but that's where it gets tricky.

I haven't been able to find, or if it's even possible, to directly manipulate the default disassembly text from one of the many notification callbacks without maybe instead using a custom processor module. I'm starting to think Disa's solution might be the most practical way to get the capitalization.

A few notes from spelunking the header files, for general interest. Information about an instruction is kept in the insn_t structure defined in ua.hpp. It's fields can be accessed from the "cmd" variable, for example:

msg("address:%a, opcode text:%s \n", cmd.ea, cmd.get_canon_mnem());

cmd.get_canon_mnem() is a pointer to a function which retrieves the opcode text (i.e. "mov", not "MOV" from the .rdata section of pc.w32 processor module that disavowed pointed to. So that field in the insn_t/cmd structure cannot be directly modified.

There are several notification callbacks one can use (enum hook_type_t in loader.hpp), each with dozens of events which can be hooked. The most practical here are probably from the processor module (HT_IDP - idp_notify events defined in idp.hpp) or the user interface (HT_UI - ui_notification_t events defined in kernwin.hpp).

There are examples of using these notification callbacks in the SDK directory, or like the simple one here:
http://www.hexblog.com/?p=54

Also this is useful for plugin writing in general:
http://www.binarypool.com/idapluginwriting/


As for producing capitalized text, I just took the default void idaapi out(void) function found in most of the /module/out.cpp files and added a simple conversion before the final MakeLine() call:

Code:

...
// added code -----------------------------------------------------

for(int i = 0; i < sizeof buf; i++)
{
buf[I] = toupper(buf[I]);
}

// end added code -------------------------------------------------

MakeLine(buf); // pass the generated line to the kernel
}


This was inserted into several different HT_IDP and HT_UI notification event callbacks and did produce the extra capitalized disassembly text, but as I said I couldn't find a way to have it *replace* the original. Also, it's a pretty crude brute force capitalization, text such as API names are also converted, so it would need to be made selective.

Some of the idp_notify events such as custom_out, custom_mnem and others seems like they might be likely candidates, IF you can convince the kernel not to display its default disassembled instruction and use yours instead, but I still can't figure out if that's possible.

It's been fun though, thanks for the ride

Aimless
March 16th, 2013, 23:43
Thanks Kayaker, I'm trying to get this done too...

Somewhere it implies that the entire text of the disassembly has to be manipulated and redrawn.

I think the only way to see this happen consistently is for Ilfak to put this as an option in IDA.

I recall asking this in the IDA Forums, way before Ilfak and Pierre separated (back then it was Data rescue, and being a member of the board didn't require you to have a license) and Pierre gave me a page long description of how difficult it is. With his usual rambling of how IDA Sales are getting affected. This was IDA 3.92 I think...

Well, let's hope Ilfak frequents these boards and sees this post.



Have Phun

ZaiRoN
March 20th, 2013, 14:50
I don't think hooking represents the best choice this time because when the installed callback (i.e. HT_IDP and HT_UI) starts to catch events the deadlist is already on the screen... everything should be done when the file is fully loaded.
So, it seems like there are two ways and Kayaker described a possible way. Besides that I think you can try directly with the ui specific kernel services, there's a specific section inside kernwin.hpp. Take a look at it giving an eye to the "Custom viewer sample plugin" provided by Ilfak.