IDA (Interactive Disassembler) tips and tricks
makeing sense of listing output
I use this c++ program to parse LST output files
into a nested callflow.
this sometimes gives a clearer view of what is happening.
you can find a compiled version here.
how to setup stackframes
left are disassembled example instructions, right is the action to
take based on that line. alt-k should be executed on the line with 'sub'
alt-p anywhere in the function. sometimes the keyboard shortcut 'alt-p' does not
work, in that case just choose it from a menu.
stmfd sp!, {r4-r7,lr} -> [alt-p] set sizeof saved regs to 0x10
sub sp,sp,#0x24 -> [alt-p] set sizeof locals to 0x24
-> [alt-k] set sp diff to -0x10-0x24
... [sp,#4] 'k' set to stack var
sometimes a function wants to take a pointer of one of the first 4 arguments,
for instance in this simple example:
int somefunction(FILE *f, char c)
{
return fwrite(&c, 1, 1, f);
}
in that case the start of the function will look like this:
stmfd sp!, {r0} -> do not count these in the save regs count.
stmfd sp!, {r4-r7,lr} -> [alt-p] set sizeof saved regs to 0x10
sub sp,sp,#0x24 -> [alt-p] set sizeof locals to 0x24
-> [alt-k] set sp diff to -0x10-0x24
... [sp,#4] 'k' set to stack var
writing IDA extensions
several ida extensions are possible:
extension | description | interface struct | headerfile |
idp | processor module | processor_t LPH | idp.hpp |
plw | plugin | plugin_t PLUGIN | loader.hpp |
ldr | loader | loader_t LDSC | loader.hpp |
idc tips and tricks
easy execute of current (shift-f2) idc code
The current shift-f2 manual idc code is stored in idc function named _idc
.
if you add a hotkey AddHotkey("Shift-I", "_idc");
you can call the current idc func
at any time with an easy shortcut. ( without having to type shift-f2 + alt-enter )
example usage:
auto ea,b;
for (ea=SelStart(); ea<SelEnd() ; ea=ea+4) { MakeUnkn(ea,0); }
b=SelStart()+4;
MakeDword(b-4);
MakeArray(b-4, (SelEnd()-SelStart())/4);
OpOffset(b-4, b);
i use this piece of idc code to convert unrecognised jumptables into a jumptable.
I use text search (alt-t) to search for regular expression "PC,.*,"
then select the unrecognised data part, press shift-I.
see if it was correct. then ctrl-t to find the next.
define functions without having to run an .idc file
if you start the contents of the shift-f2 manual idc window with '}'
and follow it with a function definition like 'static fname() {...'
and omit the terminating '}'
you can add idc functions interactively.
example usage:
AddHotkey("Shift-O", "HK_showrefs");
}
static HK_showrefs() {
auto ea,r;
ea=ScreenEA();
Message("%08lx: Rfirst/Rnext: ", ea);
for (r=Rfirst(ea); r!=-1 ; r=Rnext(ea,r)) { Message(" %08lx", r); }
Message("\n");
Message("%08lx: RfirstB/RnextB: ", ea);
for (r=RfirstB(ea); r!=-1 ; r=RnextB(ea,r)) { Message(" %08lx", r); }
Message("\n");
Message("%08lx: Dfirst/Dnext: ", ea);
for (r=Dfirst(ea); r!=-1 ; r=Dnext(ea,r)) { Message(" %08lx", r); }
Message("\n");
Message("%08lx: DfirstB/DnextB: ", ea);
for (r=DfirstB(ea); r!=-1 ; r=DnextB(ea,r)) { Message(" %08lx", r); }
Message("\n");
this will add a function for hotkey shift-o.
which will display all references to and from the cursor address
things I would like to see in IDA
note: this list is only added to, over the years, several of these issues have been resolved in ida now.
- in order to get rid of large blocks of uninteresting data in the listing.
it would be nice to have a 'dup' construct in data for the ARM assembler.
- in newer versions of IDA, you can hide uninteresting sections
- in stead of seeing references from constant pools, you should also be
able to see indirect code references through the pools.
- it would be nice if the code analyser would print deductions about
register values in a status line, such that if my cursor is on a specific
line, I will be able to tell at once what the values of my registers
are. ( the values should be expressed as equations, equating to
register values since the last point in the control flow where values
became ambiguous )
- it would be nice if you could reorder instructions, to group together
stuff that belongs together, most compilers reorder instructions for optimal
pipeline usage, which is not nescesarily the most readable.
- in hotkeys.idc
I implemented this for arm and thumb code.
- on the arm, often constants are constructed using multiple instructions,
it would be nice if you could group such instructions, in a way that the resulting
operand value is usable as an offset.
I have seen this concept called 'constant folding'.
- the latest armmodule has support to convert MOV+arithmenticop to a MOVL
macro instruction.
- on the ARM often functions use different base offsets to get to the same
dataoffset. currently I know of no way to have them all point into the
same structure. ( or is that what the first question of 't' is for? )
- sometimes you can do this by selecting the constant, and typing 't', this will open a special struct offset window.
- i wrote 'setregofs' to automatically find the register value, and change the offset occordingly.
- in that case, it would be nice if you could point to a structure variable
instead of having to manually calculate the offset
- it would be nice if pointers to the first item in a struct would also
be displayed as such, now when there is no offset in the instruction,
it cannot be changed to a different operand.
- this is fixed in later ida versions.
- but still, now if you have a struct within a struct, there is no way of specifying which name to display. ( example: struct_1 or struct_1.var_1 or struct_1.var_1.entry_1 )
- see alt-y or ctrl-z for a partial solution.
- it would be nice if you would be able to make comments in specific instances of structs
- also the 'real' addresses next to the struct items would be more useful than
everywhere the start of the struct. ( same for arrays )
- a way to easily change all large repeated sequences to 'dup' would be nice too.
- see 'summarize_unk()' in formatdata.idc
- it is quite annoying that moving the mouse cursor out of the window in certain ways
causes exceptions.
- this seems to be related to other 'allways-on-top' applications, like the taskbar, or winamp.
- ida should notice that the arm-instruction sequence "MOV LR,PC + MOV PC,Rn" is the same
as "CALL Rn"
- newer versions of IDA do so.
- also a common arm-instruction sequence to jump to thumb mode is 'MOV Rn, subroutine+1 + BX Rn'
- newer versions of IDA do so.
- when a subroutine ends with 'B' to another sub, this is seen as a 'j' xref, in stead of a 'p' xref.
- see 'FixJumpCalls()' in formatdata.idc
- functions with jumptables in them are not recognized as functions.
- it would be nice if the thumb align instructions would be automatically converted to 'align'
- the 'l' format parameter to Table and MakeTable take care of this
- restrict automatic constant->offset conversion to offsets within a specific range. such that code at 0x33f0000 using a constant 0x100 will not create a reference to 0x100, but just assume the constant to be numeric.
- arm-bug: "add<cond> sp,sp,#imm" should only modify stack ptr when <cond> is AL
- would be nice, if you could create a flow graph, excluding all hidden code sections.
... i usually create hidden sections for all error handling, which is irrelevant to the
main flow of a function.
- how do I tell the stackvar analyser how much stack a indirect function purges?
( if I specify it per call, with alt-k, then reanalysing the function destroys all the stackoffset information again )
- it would be nice if the alt-f2 script window were larger.
and allowed you to select from a range of database-attached scripts.
automatically supplying ScreenEA, or Selbegin/end as parameters.
( sort of like with 'perl -ne' which automatically iterates over args.
- it would be nice to be able to view the common ancestor in call tree from 2 specific points in the code.
by graphing multiple trees together.
- a feature to automatically add struct members when they are currently undefined.
- 'setthis' and 'setregstruc' handle this.
- arm problem: mov R0, #0x1234 ; add R1,SP,R0 ; -> you cannot make 0x1234 into a stackvar.
- currently you can restrict several functions to 'not-library'-functions. it would be nice if this could be controlled more finegrained. ... like specifying what classes of library functions.
- can the trace window be indented?
- can you add user specified expressions to trace events.
- you can set the breakpoint expression to 'Message(....)'
- can the idc editor be replaced by another editor?
- why can't you define functions in the shift-f2 window
- you can, start with '}' - to close the implicit _idc function definition. and omit the last '}' of your own function
- variable number of arguments to user defined idc functions would be nice.
- a more convenient array / hash syntax for idc?
- need option to restrict automatic data analysis to aligned data.
- operations on groups of functions - like 'set color', or 'change flags' would be nice.
- script control of the debugger would be nice.
- script control of current/selected in other windows would be nice.
so you can operate on the 'current struct', or 'current function'.
- sometimes, stack vars do not want to be stackvarred
- sometimes, a var referenced as ESP, without offset, can not be changed into a stackvar.
- it is not possible to define signed numbers.
ida allows you to display a number either as large negative, or normal, but not as two's complement.
- how do i tell if the sign of an operand was changed with 'OpSign', in IDC.
- how do i access values from the PE header of the current file?
- there is a netnode named "$ PE header"
- supvals contain the o32 headers
- the value is the binary PE header itself.
- how do i enumerate all defined names?
- probably you can do this using some netnode prev/next function
- how do i set the indirect called function ( like often happens in x86 asm ) ... alt-F11
- it would be nice to have the current search term highlighted in the disassembly
- imported names from a .pdb file for unicode strings, are completely unreadable, like ?AAx?AAy?AAz ... etc.
- it would be nice to have a keystroke to toggle between 2 windows like 'ctrl-wp' in vi, or alt-tab in windows
- it would be nice if you could cut/paste struct defs from one ida instance to another, without going through, 'save typeinfo', edit .idc, paste in exec window
- it would be nice if you could have more control of how the hex-view window displays it's contents.
- if you click on the gap in the navigator, ida should jump to one of the segments next to the gap, this would make it much easier to navigate to a segment start/end.
things to investigate
- use nalt.hpp, netnode.hpp to dump entire database contents
- done: see dbdump
- investigate expr.h, ( IDC functions ), create tool to manage idc functions stored in netnodes in the database.
- done: see scriptcmds
- create advanced trace manager, automatically adding trace functions with
expressions which write a logfile about parsed library function parameters.
- possibility of adding a perl interface to ida.
- done: see idcperl5
- possibility of adding IDC functions to control debugger.
- fixed: since ida5.2 there is such support in idc.
- create a navigate toolbar, move to next ins, end func, next def, next undef, next data, next code, ...
- i need a single keystroke, to move to the next xref.
- a history of previous searches, and where they were interrupted with a new one, to be able to complete all previous lines of research. ... like a personal stacktrace
- a plugin which displays a little info about the assembler instruction under the cursor would be helpful.
- implement iterators for several items, like curselheads, segments, functions, names
- create plugin, which adds regex functionality to IDC, string matches, regex filter of lists ...
- done: see 'scriptcmds'
- implement 'grep', 'map', and 'reduce'
- done: see 'scriptcmds'
- look at idapython, to see how to implement something similar for perl.
- done: see 'idcperl5'
- do something similar like idcperl5, for pugs, perl6, or parrot.
-