Log in

View Full Version : Reversing our own tools


crUsAdEr
November 9th, 2002, 12:41
Hi guys,

I decide to start this project here to reverse one of our tool... imprec 1.4.2+ by MackT... I have tried to contacted him to ask his permission first before start a project on this board but i couldnot find his email and he hasnt been on irc for a motnh or so i heard... so if you do not like the idea this project at all then just drop me a note and I will STOP this project immediately...

Basically, new AsProtect version fill in garbage in IAT so Imprec/Revirgin finds lots of garbage IAT entrys... which makes tracing n disassembling slower and annoys me... so i want to implement a new feature *Remove invalid thunk* on the right click menu of Imprec, which check all the invalid IAT entries and remove them automatically... since Imprec already has a Cut/Remove thunk feature... it should not be too hard to add in a few lines of invoking IsBadPointer :>... that is the idea and it is fairly useful so i hope ppl will join in this project as well...

Hmm.. so okie, Zairon, how do I start :>? just give me a hint :>...

Thanx,
crUsAdEr

P.S : if any of you can contact MackT, would you kindly please help me convey my msg and I will immediately stop this project if he wishes so! Thanx.

Kayaker
November 9th, 2002, 13:38
Sacrilege, Blasphemy! Heretic, Defiler! Have you no Shame??!

Actually, this was in reply to your post in the Snippet thread but I see you've carried it into a new project, cool. Here's a start for handling the right click feature.

Heh, oh what the heck... TrackPopupMenu is what you're looking for. Throw RV into DeDe and you'll see the right click popup menus and their OnClick events in the main form. To trace set a bp on TrackPopupMenu and make note of the 6th param, handle of owner window. Allow the popup menu to show and select one of the menu items (I wouldn't suggest Tracer unless you like BSODs), and you should return to SI immediately after the TrackPopupMenu API. A message has now been posted to the owner window informing it of your selection.

Now set a BMSG hwnd WM_COMMAND where hwnd is that 6th param and let it run. You should break in Kernel.Alloc on something that looks like:
push 1180E1B
push 30000
jmp 014f:7616

That 1st push statement address is the very start of the Windows message handling routine. You can set a bpx on that address directly (qualify the bp with your regular program CS: value since you're in the wrong context), and let SI run again. You should break and you can start tracing, watch the hWnd, wParam and lParams associated with the WM_COMMAND message being pushed in the various calls and you should quickly find the CMP EAX, 111 call. You can now insert your patch point jump here as we did above, and your patch will handle the message from your new menu item.

The next trick will be to add a new menu item to the Popup Menu. You can probably find one of the menu creation APIs doing this and use CreatePopupMenu, AppendMenuItem, InsertMenuItem or whatever to add your own. Check out the list of existing IDs used and use a unique one (RV uses Tracer=3, Edit=4, Reset=7, etc.).

Have fun with the modifications

Kayaker

ZaiRoN
November 9th, 2002, 15:03
Hi crUsAdEr,Kayaker

Kayaker, you are damn fast, did you sleep sometimes ;p

Here is how ImpRec works:
ImpRec loads the poupmenu dynamically using the function CreatePopupMenu which returns the handle of the newly created menu.
When the new menu is created the subitems are added using the API InsertMenuA:
Code:
BOOL InsertMenu(
HMENU hMenu, // handle of menu (returned by CreatePopupMenu)
UINT uPosition, // menu item that new menu item precedes
UINT uFlags, // menu item flags
UINT uIDNewItem, // menu item identifier or handle of drop-down menu or submenu
LPCTSTR lpNewItem // menu item content
);


The syntax is clearly enough. If you want to add a separator line remember to put NULL as lpNewItem. The first InsertMenuA call defines the first menu voice, the second call puts the item under the first and so on.
Finally, the API used to display the menu is the function TrackPopupMenuEx:
Code:
BOOL TrackPopupMenuEx(
HMENU hmenu, // handle of menu
UINT fuFlags, // positioning flag
int x, // horizontal position
int y, // vertical position
HWND hwnd, // handle to the window that owns the menu
LPTPMPARAMS lptpm // NULL
);

Yu have all the necessary to add a new item
Now, the only thing you have to do is find the messages handling routine. I think you can follow Kayaker's explanation or you can work directly on the SysTreeView32 control used by ImpRec

ZaiRoN

tgodd
November 9th, 2002, 17:00
Here is a C snippet to create a Taskbar Menu.
It's easy to convert it to assembly code.
Everything you need is here.

Hope this helps.



HANDLE hmHandle;
HMENU myMenu;
HICON myIcon;
NOTIFYICONDATA myIconData;
WNDCLASS myWndClass;

hmHandle = GetModuleHandle(NULL);

myMenu = LoadMenu(hmHandle, IDR_MENU1);
myIcon = LoadIcon(hmHandle, IDI_ICON1);

myWndClass.style = 0;
myWndClass.lpfnWndProc = WndProc;
myWndClass.cbClsExtra = 0;
myWndClass.cbWndExtra = 0;
myWndClass.hInstance = ghInst;
myWndClass.hIcon = myIcon;
myWndClass.hCursor = 0;
myWndClass.hbrBackground = 0;
myWndClass.lpszMenuName = 0;
myWndClass.lpszClassName = "MyClassName\0";
myWndClass.hIcon = myIcon;

RegisterClass(&myWndClass);
myHWnd = CreateWindowEx( 0, "MyClassName", "MyWindowName", 0,0,0,0,0,0,0, hmHandle, 0);

myIconData.cbSize = 58;
myIconData.hWnd = myHWnd;
myIconData.uID = 'MYuId';
myIconData.uFlags = 7;
myIconData.uCallbackMessage = 0x400;
myIconData.hIcon = myIcon;
strcpy (myIconData.szTip, "This is my tip text!!!\0";

Shell_NotifyIcon(NIM_ADD, &myIconData);





LRESULT WINAPI WndProc(HWND hWnd,UINT uMessage,WPARAM wParam,LPARAM lParam)
{
POINT myP;
HMENU tmpMenu;

switch(uMessage)
{
case WM_USER:
switch(lParam)
{
case WM_RBUTTONUP:
GetCursorPos(&myP);
tmpMenu = GetSubMenu(myMenu, 0);
TrackPopupMenu(tmpMenu, 4, myP.x, myP.y, 0, hWnd, 0);
return 0;

default:
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}

case WM_COMMAND:
switch(wParam)
{
case ID__ABOUT:
sprintf(ErrString,"This is my About Box!!!";
MessageBox( 0, ErrString, "ABout", 0x40);
return 0;

case ID__MENU1:
sprintf(ErrString,"This is my Menu #1 Option!!!";
MessageBox( 0, ErrString, "Menu #1", 0x40);
return 0;

case ID__MENU2:
sprintf(ErrString,"This is my Menu #2 Option!!!";
MessageBox( 0, ErrString, "Menu #2", 0x40);
return 0;

case ID__EXIT:
DestroyWindow(hWnd);
return 0;

default:
return 0;
}

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}

}





Regards,
TGODD

crUsAdEr
November 10th, 2002, 12:43
Thanks guys,

I have located places to intercept the message loop and decide on how to patch it... right now i am having difficulty identifying the routine handling the Import Tree itself, as in accessing it and how to remove them from the list...

Any suggestion on how i should try to identify those VC++ routine?

Thanx
crUsAdEr

ZaiRoN
November 10th, 2002, 17:08
Hi crUsAdEr,

The message handlers routine seems to be after the call of TrackPopupMenuA function.
In fact, after this call, the program controls if one of the items of the popup menu has been pressed (cmp dword ptr [esp+24],111h); if it has been pressed, it controls which it is the item pressed through the value contained in ecx.
This is the enumeration given to the items:

Invalidate function-0
Trace level1-2
Trace level2-3
Trace level3-4
Cut thunk-1
Delete thunk-5
Switch *LOADER*-8
Expand all nodes-6
Collapse all nodes-7

Except 'Switch *LOADER' all these items are handle using the jump [ecx*4+41620C]. Here you will find all the information that you have need.
Quote:
as in accessing it and how to remove them from the list...
I'm not totally sure but from what I have seen, the program uses the message of TVM_DELETEITEM in order to delete an item from the list; you can recognize it from the 'push 1101' before the call of SendMessageA.

For more information on TreeView control, you can take a look at:
http://spiff.tripnet.se/~iczelion/tut19.html
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/treeview/reflist.asp

Hope it helps!

ciao,
ZaiRoN

crUsAdEr
November 10th, 2002, 23:25
yeah.. thanx zairon...

was wondering wat the hell is that message :> "push 1101"... tried searching through windows.inc but it is not there... okie... time for more research... sign... i should have learnt C last time instead of delphi ... ah well

shall keep repoting my progress here... does anyone else wanna join in as well ?

cheers,
crUsAdEr

ZaiRoN
November 10th, 2002, 23:58
Quote:
was wondering wat the hell is that message :> "push 1101"... tried searching through windows.inc but it is not there.

The message is TVM_DELETEITEM and there is but it's *hidden*:
TVM_DELETEITEM equ TV_FIRST + 1 <-- 1100 + 1 = 1101

ciao!
ZaiRoN

foxthree
November 11th, 2002, 07:41
The best way to attack these kinds of problems is to use DLL injection techniques rather than doing inline patches. It is far easier to code a separate DLL and then to inject it into the process ... and also easier to debug

Look at samples from the DLL Injector "guru" EliCZ

Signed,
-- FoxThree

crUsAdEr
November 13th, 2002, 05:15
On the way there... :>

Yep thanx Zairon for the input... been busying myself reading about Treeview... i have a another slight problem... I am not quite sure how to unselect an item in the treeview... there is TVIS_SELECTED state value, there is TVM_SELECTITEM... but there isnt any TVIS_UNSELECTED ... so do i just set State to TV_ITEM to be 0???

I was trying something like that but it doesnt seem to work... so could you show me a short example of using TVM_SETITEM...

thanx
crUsAdEr

ZaiRoN
November 13th, 2002, 11:22
Hi crUsAdEr,
reading msdn I have found something that could help you:
Code:
lResult = SendMessage( // returns LRESULT in lResult
(HWND) hWndControl, // handle to destination control
(UINT) TVM_SELECTITEM, // message ID
(WPARAM) wParam, // = (WPARAM) (DWORD) flag;
(LPARAM) lParam // = (LPARAM) (HTREEITEM) hitem;
);

where:
hitem --> Handle to an item. If hitem is NULL, the control is set to have no selected item.

That might be the way. I'm a little bit busy and I can't try...

good luck!
ZaiRoN

tgodd
November 13th, 2002, 13:58
One of the best places I have found to get info on windows
API programming is at this site http://www.mvps.org/vbnet/
It's a VB sight but its easy to do the translation to assembler.
After all it is windows API you are using.

Check it out.

Regards,

TGODD

crUsAdEr
November 13th, 2002, 14:17
Zairon : I just want to unselect 1 item and keep the rest selected, but thanx anyway.. dont worry i will get on on my own :>....

FoxThree : yeah, a dll is easier but heeding Kayaker advice, i am using Code Snippet Generator for this project.. seems to work fine :>...

tgodd: thanx a lot, i will check it out...


cheers guys,
crUsAdEr

P.S : Code Snippet Generator assemble my patch fine but refuse to patch the file or export binary saying my code use a function that is not present in the target file??? I amsure all APIs used are imported, i even add another set of import API (those that i use) just in case but still the same error msg ? Can someone tell me what is wrong?

NervGaz
November 13th, 2002, 17:29
deselecting 1 item would as far as I can figure the PSKD documentation out would be to zero out the state member of the LV_ITEM struct... Doesn't seem to be any other way...

Kayaker
November 13th, 2002, 17:36
Hi crUsAdEr,

I had that Snippet Creator error message as well when I used an API that wasn't on the import list, even though I had added the import via the menu. I think it had something to do with the order you did it in, I think you need to add the imports then reopen the import-patched file as the project file before trying to assemble any patch code. Something like that anyway, but yeah it seemed a bit quirky that way.

I agree with FoxThree that dll injection techniques are fun, EliCZ's stuff is without equal for sure. I've never had much the need for such complexity though, a simpler basic approach much like Iczelion's loader/injection implementation in IczDump has worked wonders for me.

You could also do a combination inline patch/dll 'inject' where the 'patch' is a LoadLibrary/GetProcAddress routine that simply calls your own dll. This way you've got a small dll loading routine you can patch into any app, somewhere in the msg handling routine let's say, but the bulk of your coding can be done in your own dll in a more familiar dev. environment.

All in all I still like SC a lot

Kayaker

sv
November 14th, 2002, 09:36
Hi crUsAdEr

I have done some check in my rebuilder to avoid invalid thunk too.
I think you have to do 'IsBadPointer' but it's not enough (some bad entries aren't badPointer!).
My solution is to check in code section, for each thunk, if there is a call [thunk], jmp [thunk] or mov xxx, thunk.
It's not perfect but for the moment it works pretty well.

My 2 cents

SV

crUsAdEr
November 14th, 2002, 19:06
Hi sv,

Thanks for the input.. yeah Imprec also has already done its check with IsBadCodePtr already.. so i will need a more rigorous check algorithm but that is for the later part...

Does it take long for you to do that? Search for reference for each pointer? I was afraid it might be slow...

Right now i am working on general reversing skill, adding functionalities and coding in asm... the dudes in win32asm board have helped me fixed some bug in dealing with Treeview... now i am off next to find out where Imprec store the target exe PId and process handle...

thanks guys ofr the help, reversing is really quite fun... it makes you feel like you can make any programs do what you want :>... though i am no where that good yet but ah well ...

Regards,
crUsAdEr