View Full Version : OllyScript/ODbgScript: great GPA bug !
shERis
January 18th, 2006, 07:33
BUG in GPA !
There is a great bug in GPA, but I don´t know why.
If you have a command GPA "Any_Proc","COMCTL32.DLL", you´ll get a wrong (non existing) address of this "Any_Proc".
Why ?
I tried the following:
1. I loaded notepad.exe in a first instance of Olly (could be another app using COMCTL32.DLL)
2. I made a little script with gpa "CreateToolbar","COMCTL32.DLL" and loaded it
3. I started another instance of Olly, attached first instance of Olly and run it
4. I set a BP on CALL near kernel32.LoadLibraryA in GPA command in ODbgScript-section in second instance of Olly
5. I singlestepped the script in first instance of Olly with S
6. Olly stopps in second instance at that CALL
7. Wonder !?!
I found the following:
In second instance of Olly there are all plugins in shown memory, in first instance not.
In first instance there is COMCTL32 in a high memory space. But in second instance of Olly there is at the same place a DLL called COMCTL_1. And there is at another place COMCTL32!!! At this address there is nothing in first instance of Olly! GPA now examines the address of CreateToolbar in COMCTL32 in second instance in a lower space and gives it to $RESULT. But in first instance of Olly this address is invalid!!!
Does anybody know this behaviour and how to eliminate it, so that GPA results the right address of COMCTL32 procs ???
shERis
January 19th, 2006, 08:07
I think, that GPA now results the proc addresses of the named proc in OllyDbg process and NOT in the app process.
All other commands seem to be executed in app process.
Does anybody know how to get proc addresses in another loaded process (it is the loaded app process, here in the example notepad.exe) ?
nick_name
January 19th, 2006, 08:49
the GPA code for ODBGscript is like the following :
======================================
bool OllyLang:
oGPA(string args)
{
string ops[2];
if(!CreateOperands(args, ops, 2))
return false;
string proc, lib;
if(GetSTROpValue(ops[0], proc) && GetSTROpValue(ops[1], lib))
{
HMODULE hMod = LoadLibrary(lib.c_str());
if(hMod == 0)
{
//errorstr = "No such library: " + lib;
variables["$RESULT"] = 0;
variables["$RESULT_1"] = "";
variables["$RESULT_2"] = "";
return true;
}
variables["$RESULT_1"] = lib;
FARPROC p = GetProcAddress(hMod, proc.c_str());
FreeLibrary(hMod);
if(p == 0)
{
//errorstr = "No such procedure: " + proc;
variables["$RESULT"] = 0;
return true;
}
variables["$RESULT"] = (DWORD) p;
variables["$RESULT_2"] = proc;
return true;
}
variables["$RESULT"] = 0;
return false;
}
======================================
in the 2nd instance of olly, it breaks on LoadLibraryA becoz GPA
has a LoadLibraryA call inside it's code ... pretty obvious
ODBGscript.dll is loaded under olly ... so in 2nd olly, putting a bp on
LoadLibraryA means from the 1st intance, every call for LoadLibrary would
break on that bp of 2nd instance ... which had just happened
in both instances, i loaded the following script ...
===========================
gpa "CreateToolbar","COMCTL32.DLL"
msg $RESULT
===========================
both msgbox popped up with the same address : 5D0C8FA3
shERis
January 19th, 2006, 14:09
Hi nick_name!
I myself know code of GPA and what it does.
Let me tell more:
1st instance of Olly debugs app (notepad.exe).
2nd instance of Olly debugs Olly of 1st instance.
ODbgScript is loaded by Olly - it´s loaded in both instances! But only in 2nd instance you can debug ODbgScript and set a BP on CALL kernel32.LoadLibraryA in ODbgScript code.
When you run a script with GPA then 2nd Olly breaks at LoadLibraryA.
But when you look at memory map window in both Olly´s, you´ll find the following (address could vary for you):
1st instance:
71950000 COMCTL32
2nd instance:
71950000 COMCTL_1
77310000 COMCTL32
When you execute GPA, then it results addresses of COMCTL32 in 2nd instance, it doesn´t matter in what instance of Olly you do. You´ll always get 77310000. But this is wrong!
It seems that Olly (1st instance) loads COMCTL32 twice in its process. One for the app and one for Olly itself.
But the right version of COMCTL32 is renamed to COMCTL_1, which has the same address. Therefore you´ll always get the wrong address of 2nd COMCTL32, which does not exist in app process.
So it is necessary to get proc address in app process and not in Olly process.
You can make a little test:
========================
gpa "CreateToolbar","COMCTL32.DLL"
mov addr,$RESULT
gn addr
msg $RESULT
========================
and now you can guess, what you will see.
shERis
shERis
January 19th, 2006, 14:22
What I forgot to say:
This ugly behaviour is only with COMCTL32.DLL. All other libs are at the same memory location in 1st and 2nd instance of Olly, therefore reading app process or Olly process doesn´t matter. But GPA always should result app process !!!
nick_name
January 19th, 2006, 17:15
shERis i'm getting a little deviations from ur situation
in both instances i'm getting
gpa "CreateToolbar","COMCTL32.DLL"
msg $RESULT -------> 5D0C8FA3
but with gn this is returning ZERO !!!
in 1st instance, my comctl32 is loaded at
=========================
Address=773D0000
Size=00001000 (4096.)
Owner=COMCTL32 773D0000 (itself)
Section=
Contains=PE header
Type=Imag 01001002
Access=R
Initial access=RWE
=========================
**************************************
**************************************
now i tried this ...
opened 1st instance of olly(debugger)
loaded another olly (2nd instance - debugee) into it ... ( not attaching )
now in the mem.map :
============================
Memory map, item 35
Address=5D090000
Size=00001000 (4096.)
Owner=COMCTL32 5D090000 (itself)
Section=
Contains=PE header
Type=Imag 01001002
Access=R
Initial access=RWE
============================
now i press f9 under the 1st instance (debugger) ....
the 2nd instance (debugee) runs ...
just after that ... in the 1st instance(debugger), the mem.map shows
wht u said ...
===========================
Memory map, item 331
Address=773D0000
Size=00001000 (4096.)
Owner=comctl_1 773D0000 (itself)
Section=
Contains=PE header
Type=Imag 01001002
Access=R
Initial access=RWE
===========================
now here is the problem ...
==========================================
The LoadLibrary function maps the specified executable
module into the address space of the calling process.
HINSTANCE LoadLibrary(
LPCTSTR lpLibFileName // address of filename of executable module
);
.... ..... .....
The first directory searched is the one directory containing the
image file used to create the calling process (for more information,
see the CreateProcess function). Doing this allows private
dynamic-link library (DLL) files associated with a process to be found
without adding the process's installed directory to the PATH environment
variable.
Once the function obtains a fully qualified path to a library module
file, the path is compared (case independently) to the full paths of
library modules currently loaded into the calling process. These
libraries include those loaded when the process was starting up as well
as those previously loaded by LoadLibrary but not unloaded by
FreeLibrary. If the path matches the path of an already loaded module,
the function just increments the reference count for the module and
returns the module handle for that library.
==========================================
with sysinternal's process explorer ... my 1st instance ( debugger ) shows
1. D:\WINDOWS\system32\comctl32.dll [version : 5.82]
2. D:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2649_x-ww_aac16c8b\comctl32.dll
[version : 6.0 (xpsp.050406-1732)]
2nd instance only loads :
D:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2649_x-ww_aac16c8b\comctl32.dll[version : 6.0 (xpsp.050406-1732)]
**************************************
**************************************
now , from MSDN
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwxp /html/xptheming.asp
("http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwxp/html/xptheming.asp
")
ComCtl32.dll Version 6
All applications running on the Windows XP operating system have a non-client area, which includes the window frame and non-client scrollbars. A visual style is applied to the non-client area by default. This means that the appearance of the non-client area is specified by the visual style that is currently installed. To apply a visual style to common controls in the client area, you must use ComCtl32.dll version 6 or later. Unlike earlier versions of ComCtl32.dll, version 6 is not redistributable. The only way you can use version 6 of the dynamic-link library (DLL) is to use an operating system that contains it. Windows XP ships with both version 5 and version 6. ComCtl32.dll version 6 contains both the user controls and the common controls. By default, applications use the user controls defined in User32.dll and the common controls defined in ComCtl32.dll version 5.
If you want your application to use visual styles, you must add an application manifest that indicates that ComCtl32.dll version 6 should be used if it is available. Version 6 includes some new controls and new options for other controls, but the biggest change is support for changing the appearance of controls in a window.
now i think, this is a problem with WINDOWS itself tht it is loading both
version 5 and 6
and a possible solution could be to determine which version is loaded and
which version of comctl32.dll function user wants to be resolved by GPA
nick_name
January 19th, 2006, 17:35
http://addressof.com/blog/archive/2004/02/13/384.aspx ("http://addressof.com/blog/archive/2004/02/13/384.aspx")
I can use IsThemeActive from uxtheme.dll that would tell me whether or not visual styles is enabled. But prior to that, I need to test that the OS version is greater than 5.1 and do a LoadLibrary to test that the uxtheme.dll exists. Not a problem; pretty simple really. So great, I can determine if Windows is themed. But, what if I didn't use EnableVisualStyles()? My application is still using the previous common control library. Then comes in the IsAppThemed() method in uxtheme.dll. Sounds like it's the one I want... but it appears to always return true when testing under WindowsXP that has themes enabled and no EnableVisualStyles() being used. If the application is not using visual styles, why does this function return true? Grrrr.
Epsylon3
January 20th, 2006, 09:09
wow no comments

shERis
January 20th, 2006, 21:34
Hi nick_name!
I played a little bit with OllyDbg and found the following:
When Olly is loaded, COMCTL32 from windows system32 directory is loaded into memory. It is shown as COMCTL32 in memory map window.
When Olly begins to run, it loads COMCTL32 from windows WinSxS\x86_Microsoft.Windows.Common-Controls..... directory using kernel32.LoadLibraryW/kernel32.LoadLibraryExW/ntdll.LdrLoadDll. With ntdll.RtlDosApplyFileIsolationRedirection_Ustr the WinSxS path is added to filename.
COMCTL32 therefore is loaded twice. The both versions are not identical. (Process Explorer shows it very well.)
To make a difference between the two instances windows changes the owner name to COMCTL_1 of the second COMCTL32.
I don´t know why Olly does this and I think it doesn´t matter for our problem.
I think there must be a simple possibility to get the proc addresses of the loaded modules in the debugged process using
VAL_HPROCESS (HANDLE) Handle of debugged process
VAL_PROCESSID Process ID of debugged process
VAL_HMAINTHREAD (HANDLE) Handle of main thread of debugged process
VAL_MAINTHREADID Thread ID of main thread of debugged process
information of Plugingetvalue(int type).
Sysinternals Process Explorer shows it in a very effective way.
But I am no windows programmer. Please help me and Epsylon3 if you know the necessary code.
shERis
nick_name
January 21st, 2006, 02:52
a possible solution is to use
LoadLibraryEx instead of
LoadLibrary in
OllyLang:
oGPA
HINSTANCE LoadLibraryEx(
LPCTSTR lpLibFileName, // points to name of executable module
HANDLE hFile, // reserved, must be NULL
DWORD dwFlags // entry-point execution flag
);
Flag =
LOAD_WITH_ALTERED_SEARCH_PATH
..........If this value is given, and lpLibFileName specifies a path, the function uses the alternate file search strategy
Thank you shERis n' epsylon3
Powered by vBulletin® Version 4.2.2 Copyright © 2019 vBulletin Solutions, Inc. All rights reserved.