Topic created on: February 13, 2007 23:59 CST by ninjah  .
I'm creating an IDA plugin, and I want to be able to create windows similar to say the IDA Function window. Reading IDA header files has lead me to believe that there are no useful functions exported for this purpose. AskUsingForm_c() does not seem to offer anything this complex. I'm assuming I'll just have to bite the bullet and dust off the win32 part of my brain, unless someone is aware of (exported)IDA functions that can do this?
ninjah,
try looking at some existing plugins. AskUsingForm() should be able to do just what you want it to do. If there isn't something usable on the net, I have some sample code at home. Will post tonight.
cheers,
dennis
|
Use the choose() or choose2() SDK functions, in kernwin.hpp. They allow you to create windows exactly like the IDA Function window (in fact, I think that's how they're implemented internally). You define callbacks that provide the text for the column(s) and handle insertion, deletion, "visit", and edit. Your window will integrate completely into IDA, becoming a new tab just like the built-in windows.
I don't think this is wrapped in IDAPython, but I have done this extensively for normal plugins...
|
|
beautiful! i must of missed those PSUJobu. thanks.
|
No problem -- they're not well documented, though. In particular, the callbacks weren't all well documented, so if you have any issues let me know. I could dig up some of my plugin code -- don't need to mess with it normally, since now it "just works."
Since I'm a C++ OO dude, I wrapped choose() and choose2() with a C++ class hierarchy so the IDA SDK details were hidden and I just needed to override virtual functions. I'll have to see whether I can post any of that wrapper code...
|
Sorry, of course it was choose2().
I have some sample code as well, but it's pretty ugly ;-P
|
|
hmm i have things working basically, but some weird behavior. I'm trying to set the column names, which I do from the getl() callback when it passes n == 0. So I figured out that the arrptr array is where you insert column names. The weird behavior is that let's say I want two columns. So I figured that I would pass ncol as 2, and then fill in arrptr[0] and arrptr[1]. However, this only fills in the first column. So I tried passing ncol as 3, and then I filled in arrptr[0] and arrptr[2], and it worked! arrptr[1] seems to be ignored?
|
might not be the best way, but this works for me:
static void idaapi get_item_desc_callback(void *, ulong n,char * const *arrptr)
{
Function *f;
unsigned int i = 0;
unsigned int rule;
if(n==0)
{
qsnprintf(arrptr[0], 10, "Function");
qsnprintf(arrptr[1], 10, "Address");
qsnprintf(arrptr[2], 10, "Rulematch");
}
else
{
}
}
|
|
That's essentially what I did, too. Note that arrptr[] is an array of strings, and you need to copy / format your string into it (as opposed to changing the pointers).
|
Yea that's what I assumed would work. I have this:
const int NUM_COLS = 4;
const int MAX_COL_WIDTH = 20;
choose2(CH_MODAL, -1, -1, -1, -1, (void *)&iop_matches, NUM_COLS, &MAX_COL_WIDTH, iop_sizer, iop_getl, "test-win", 1);
..
void iop_getl(void *obj, ulong n, char * const *arrptr)
{
char buf[MAX_COL_WIDTH] = {0};
vector<match_t> *matches = (vector<match_t> *)obj;
deb(IDA_DEBUG_PLUGIN, "get; called with obj %a n %d arrptr %a\n", obj, n, arrptr);
if(n == 0){
// column name
deb(IDA_DEBUG_PLUGIN, "SEtting column name\n");
qsnprintf(arrptr[0], MAX_COL_WIDTH, "%s", "Function");
qsnprintf(arrptr[1], MAX_COL_WIDTH, "%s", "I DONT APPEAR");
qsnprintf(arrptr[2], MAX_COL_WIDTH, "%s", "Called from");
qsnprintf(arrptr[3], MAX_COL_WIDTH, "%s", "Instruction");
Which results in the "I DONT APPEAR" column not being there. I just have the other three in the order they are shown..
I must be messing something up somewhere else I guess, but there is no code in between..
|
MAX_COL_WIDTH should be an array of integers, not a single one. For example,
int columnWidths[NUM_COLS] = { 20, 20, 20, 20 };
...assuming you want each column to be 20 (whatever the unit is) wide. Had to look at my C++ wrapper to figure out what might be wrong, and that jumped out at me!
|
|
sweet that was it. everything is working golden now. thanks. heh that should of jumped out at me, how foolish of me. passing the address of a single simple type variable with a const pointer doesn't make much sense does it :P
|
I kind of have the opposite question (?):
Suppose a windows with a table is open in IDA (for example the one shown in the screenshot previously in this thread). Is there a way to get the text lines from it? if possible from an IDA Python script or IDC script. Otherwise, I guess I'll have to fall into plugin-land.
In short, I want to do something from IDA Python, and get, from the example, something like:
(('1', '01001929',''),('2','0100195D',''), etc.
any ideas?
|
|
I don't even know how to do that from a plugin. Perhaps possible using the BC++ visual libraries (OWL successor - the name escapes me at the moment). If you don't get any responses here, I would try asking on the Datarescue bulletin board - Ilfak can probably answer this pretty easily...
|
I think the example in sdk\plugins\choose2 show a good way to create a list and generate the column headers.
I am a beginer in IDA plug-in. I do not find how to create a popup menu item for the list window. Any one can help me?
|
You can sort of do a nasty hack, and override the delete/edit/enter callbacks and create your own menus to do other things. Using the choose2() function, you would do this:
//the text that appears when you right click on the list window
const char * const menu_popup_names[] = {"NULL", "Delete/Comment/Interest", "Toggle Audited", "Update Window"};
choose2(CH_MULTI, -1, -1, -1, -1, (void *)this,
IOP_NUM_COLS, IOP_MAX_COL_WIDTH, iop_sizer, iop_getl,
window_name, 1, 1, iop_delete_or_comment_or_interest, NULL, NULL, iop_edit,
iop_enter, NULL, menu_popup_names /* pass it in here */);
If you look at the comments for choose2() function, from kernwin.hpp, you can see the different function pointers that you pass in.
|
I have a question of my own for someone :D
How do I refresh the window without making the user hit Ctrl-u? I am adding elements to the window from a different window, and they don't appear unless I manually refresh with Ctrl-u.
|
|
kernwin.hpp: refresh_idaview_anyway()? I'm not sure if this really answers your question, though...
|
@ PSUJobu : IDA Pro is written using Borland C++ Builder , and VCL which doesnt have anything to do with owl . VCL is written purely in Delphi and there a Delphi Compiler inside Borland C++ Suit to complie VCL Delphi Sources to be linked with C++ stuff . as you might saw my forum topic before i once tried to build a Visual Component library to wrap IDA SDK using VCL so IDA developers could develop Visual plugins with ease inside borland Delphi or BCB , but due to my business its suspended for now .
btw , finally Borland decided to be dedicated to ALM business and all its compilers and IDEs including C++ and Delphi are rebranded , the name is "CodeGear" . sorry for interruption ;-)
|
Yeah, "VCL" was the name I was looking for. Actually, I assumed it was just the successor to OWL -- I didn't realize it was its own beast. Thanks for the clarification...
The whole Borland compiler thing brings back memories. So many of us learned the programming ropes on their excellent products, which were finally surpassed by M$ somewhere around VC++ 4.0. A sad day, not that I don't like VC++ / VStudio...
|
Note: Registration is required to post to the forums.
|