View Full Version : Microsoft's Rich Signature (undocumented)
Daniel Pistelli
March 4th, 2008, 21:20
In the last days I've been quite sick, so I decided that as long as I had to stay in bed I might at least use the time to do something useful (or quite so). What happened is that someone asked what the Rich Signature was. It might seems strange but in all these years I didn't even notice it, I just overlooked it as part of the dos stub (incredible but true). Unable to answer, I noticed together with this person that the subject was completely undocumented. It might not even be much important, but you might find it an interesting reading after all.
http://ntcore.com/Files/richsign.htm
Since information about this topic is non-existent, the reader might not know what I'm talking about:
Code:
00000070 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$.......
00000080 E7 B3 9D E7 A3 D2 F3 B4 A3 D2 F3 B4 A3 D2 F3 B4 糝
00000090 60 DD AC B4 A8 D2 F3 B4 60 DD AE B4 BE D2 F3 B4 `ݬ`ݮ
000000A0 A3 D2 F2 B4 F8 D0 F3 B4 84 14 8E B4 BA D2 F3 B4
000000B0 84 14 9E B4 3A D2 F3 B4 84 14 9D B4 3F D2 F3 B4 :?
000000C0 84 14 81 B4 B3 D2 F3 B4 84 14 8F B4 A2 D2 F3 B4
000000D0 84 14 8B B4 A2 D2 F3 B4 52 69 63 68 A3 D2 F3 B4 Rich
000000E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000F0 00 00 00 00 00 00 00 00 50 45 00 00 4C 01 04 00 ........PE..L.
The data between the dos stub and the PE Header. It ends with the word Rich. It is produced by microsoft VC++ compilers only and it is encrypted.
To dELTA who has been hunting me down for this article for more than a week: I hope you're satisfied now! Damn swedish bloodhound! =)
rendari
March 4th, 2008, 22:42
My good sir,
there is bored
then there is BORED bored.
and then there is HOW FUCKING BORED DO YOU HAVE TO BE TO DO THIS KIND OF LDFKJHNDFCKL? bored.
Care to guess which category you fall into?
But seriously, that was kind of an interesting (albeit long) read. Lot's of stuff I didn't quite understand that I'll have to look up. Good job
-rendari
evilcry
March 5th, 2008, 01:31
Another great Work
Congratz Daniel
Have a nice Day,
Evilcry
Shub-nigurrath
March 5th, 2008, 03:32
wondeful job mate, really interesting reading.
Nacho_dj
March 5th, 2008, 05:16
Very impressive, I like it very much. I find very interesting all your reversing work, and of course, the way of deleting such useless information in the header of the file.
Please, could you consider writting down some paper about .lib format? Many of us would find such document "a must to have" for facing any reversing task...
Grazie tante!
Nacho_dj
dELTA
March 5th, 2008, 05:25
Excellent writeup and research Daniel, seems it was worth the wait after all!
I also made a PDF of it and attached it to this post, for archival purposes.
The reason for why I'm extra interested in this is that I was wondering about this same data many years ago too, when I was experimenting with building my own exe files. You can see a question of mine related to this here:
http://www.woodmann.com/forum/showthread.php?t=4499
I asked the same question over at the asmcommunity board at the time, which fortunately got some more attention than my local post here

:
http://www.asmcommunity.net/board/?topic=11182.0
What really made it interesting though, was that someone actually posted a reverse/documentation of this header in the following thread, which was subsequently removed completely, without a trace, which added even more to the conspiracy feeling:
http://www.asmcommunity.net/board/?topic=14699
You can see my hunt for what happened to that data in those threads, even the "@comp.id" reference is mentioned in them once.
So, I'm really glad that we can close this mystery once and for all (even though I guess it's not really closed until the real origin of the value from the compiler is traced/reversed by someone...

)!
Again, very nice work Daniel!

Daniel Pistelli
March 5th, 2008, 06:34
Thanks to all you guys! Wasn't expecting so many comments!
However, dELTA what was said in those threads about the @comp.id doesn't really apply. It seems that MASM was producing a fake signature (just comp.id string xored randomly). I think the guy voluntary deleted his own post when he noticed that they were not the real answer to the question. But initially, I have to admit, it added to the mystery. Why were those post canceled, by who? Now, we know the answer. They were just not true, because based on a MASM signature and most probably the owner of these posts deleted them. I can't find another answer otherwise. It's not like it's a big secret or something.
rendari: I guess I would fall into the FOURTH category. The one you didn't mention. I was even more bored ahahah.
Nacho: If I add support for the CFF Explorer I will surely write an article about those formats. That's a promise.
tofu-sensei
March 5th, 2008, 11:13
iirc this was already partly covered in some cracking tutorial, there's also a tool called 'signfinder' which helps with patching the linker itself.
still an interesting read, though

Daniel Pistelli
March 5th, 2008, 11:29
Thanks. It's funny but at the beginning I thought of patching the linker myself, but then I figured out that I would have to patch:
x86 linker
x64 linker on x86
x64 linker on x64 (compiled in x64 i mean)
IA64 linker on x86
IA64 linker on IA64
Arm linker for WinMobile
etc.
And this with every update!!!
I figured out that it was way better writing a little script that does even something more than just removing the signature. But that's your personal choice.
dELTA
March 5th, 2008, 17:29
I have seen references to a tutorial by "goppit" (ARteam member?) about the rich signature, or at least about how to remove its creation from the linker (I doubt anyone has done a nearly as thorough analysis/documentation as Daniel just did though), but I cannot seem to find it at the moment.
Attached is the SigFinder tool (by Asterix) anyway, for reference. It contains a very small document about the Rich signature too (in Russian), but it looks to be meant mainly just to explain what the program does. Anyone who can read Russian is welcome to confirm that.
Oh, and the SigFinder tool supposedly doesn't work for more recent version of the linker, which is just the problem to expect with such a solution, just like Daniel implies above.
Shub-nigurrath
March 5th, 2008, 17:40
oh well, given that this entire subject is going to be revitalized here something I can contribute, again thanks to goppit for the discussions on this subject, well we were talking of this more than an year ago, then things are quite "mature" now.
quoting:
What was known is that these rich information contains info about your computer (a "@comp.id" identifier) and some virus writers were caught because M$ used this info to prove that the virus had been compiled on thier computer.
The "@comp.id" identifiers are XORed before being put into the stub:
MS ML.EXE Ver.6.14.8444 -> comp.id is 1220FC(You can search: FC2012)
MS ML.EXE Ver.7.00.9466 -> comp.id is 4024FA(search: FA2440)
MS ML.EXE Ver.7.10.2179 -> comp.id is 0F0883(search: 83080F)
MS ML.EXE Ver.7.10.3077 -> comp.id is 0F0C05
dELTA
March 5th, 2008, 17:45
Hey Shub, interesting indeed. But was there any proof/documentation of that statement (i.e. the "info about your computer" part)? I'm asking since it does not seem to match the empirical results of Daniel's investigation above?
Or do you mean that only the linker version is stored in that data, and not any further info about the computer than that (and that was enough to "catch" those virus writers)?
NeOXOeN
March 5th, 2008, 22:02
excelent work..
as alwasy...
dELTA
March 6th, 2008, 04:25
Some more info just posted at OpenRCE, as a result of Daniel's article being posted there too:
Quote:
[Originally Posted by igorsk]I had a look at where @comp.id is generated, and its value is basically the compiler's build number (low word) plus some compilation flags (high word).
I guess MS puts it into executable to be able to determine which compiler version(s) were used to produce it. |
Also, the following 29a article/analysis of the Rich signature (again, still less comprehensive than Daniel's) was referenced (http://mirror.sweon.net/madchat/vxdevl/vxmags/29a-8/Articles/29A-8.009), which funny enough references this board and some members of it

:
Quote:
[Originally Posted by lifewire]: things they didn't tell you about ms link and the pe header : lw, 7 july 2004 :
* Introduction
The linkers from microsoft store information about used compiler versions
to create the object and library files in the EXE files they produces. This
information is stored right after the DOS stub, and before the start of the
actual PE header.
Appearantly they wanted to hide it, since all this stuff is encrypted using
checksums and other weird ways. I must say that I don't understand much of
the way they built up the structure, it is inefficient and simply weird.
Also I don't see much use of it, unless in some strange lawsuit or something
where the question is: is this .exe file created by this compiler+linker?
Or: are these .lib's used to create this exe file? Still then there is no
good evidence, because only the used compiler versions are stored, compilers
which are used by thousands of other people too. And why does microsoft use
this strange encryption and such?
Well, as you might see, enough questions about the reason why it exists -I can't
tell you much about the use of it- but maybe I can tell you something in this
article about the structure of this stored data though.
* The Rich-Structure
The name "rich" is used because of one field of the structure, which contains
the ASCII values that form "Rich". After the DOS stub the "rich" structure is
stored. This structure is created by the ms linker and consists mainly of compiler
id's which are gathered by the linker from the used .obj and .lib files. These
compiler id's are stored in the files by the ms compiler in the 'comp.id' fields,
and contain the version number of the compiler. Newer linkers from ms also add
their linker id to the exe file.
The "rich" structure is in the following format:
a, b, b, b -- identification block / header?
compid^b, r^b -- from 0
.. -- :
compid^b, r^b -- to n
'Rich', b -- terminator
padding
Where all variables are dwords. b is the checksum i'll describe later, and
a=b^0x536e6144. This value is a hardcoded value and appearantly always used.
compid is the compiler id and b is the number of times it was encountered
over all the lib/obj files (that is an assumption, i'm not 100% sure). And
n is number of stored compid's. compid's are dwords too, the lower word is
the minor version number (0-9999 decimal), the high word is the major
number. i don't know how the high word is encoded, but 13.10 appears is
encoded as 0x60, and 7.10 as 0x5a. and yes, i see that 0x60-0x5a is the same
as 13-7 decimal, but where did the 0x53 (0x60-13decimal) came from? and where
is the 10 from the verison number stored?
The size of the "rich" structure is ((b/32)%3 + n)*8 + 0x20 bytes. the unused
space is padded with zeroes.
b is calculated in these steps:
b=sizeof(dos_stub) // (almost always 0x80)
then the checksum of the dos_stub, with the pointer to the PE zeroed out, is
calculated in the following way:
for(int i=0; i<sizeof(dos_stub); i++)
{
b += dos_stub[I] ROL i; // ROL is the x86 rotate over left operation.
}
when the default dos stub of 0x80 bytes is used, b contains now 0x884f3421
next, a checksum over the various compiler id's is calculated in this way:
for(int i=0; i<n; i++)
{
b += compid[I] ROL r[I];
}
as stated above, r appears to be the number of times that compid is
encountered in the libs/objs.
* Conclusion
The linker doesn't store your the MAC address of your NIC nor your DNA profile,
but better remove it anyway . You can write a very simple tool that will
zero out the rich structure given an exe file, or patch your linker so that it
won't get written at all. For my investigation I used the Microsoft Visual C++
Toolkit 2003 with the "same compiler and linker that ship with Visual Studio
.NET 2003 Professional!" which you can download for free from microsoft.com,
google for "VCToolkitSetup.exe". You can locate the interesting parts of code
by searching link.exe for the string 'Rich' or in the function starting at
0x459090.
* Some additional last minute notes:
Disavowed told me on the RCE board that the constant 0x536e6144 is equal to
Dan^ in ASCII, and Silver had an some additional information about "Dan":
Dan Ruder, Mechanics of Dynamic Linking, Microsoft, MSDN Library 1993, as
referenced by patent 6253258 filed by Symantec for "Subclassing system for
computer that operates with portable-executable (PE) modules". Well, that must
be "our" magic Dan, shouldn't he?
Thanks goes out to my good friend malfunction for making me interested in the
Rich stuff, to StarZer0 for a lot of things, and to a lot of other guys who
make the scene a nice place to be.
If you have anything to tell me, don't hesitate to contact me.
:lifewire / ikx - lifewire$mail.ru - ikx.cjb.net: |
Shub-nigurrath
March 6th, 2008, 04:29
@dELTA
no direct information. I just reported what I know..
Most of the thread were reporting wrong conclusions or just partial. On openRCE there's also this nice link I didn't know: hxxp://mirror.sweon.net/madchat/vxdevl/vxmags/29a-8/Articles/29A-8.009
nothing much more of what Daniel wrote.
on the google cache version of this page: hxxp://www.donationcoder.com/Forums/bb/?topic=11956.msg101196 (no more directly available) you can also find an old interesting discussion. It seems to me that no one really found what those informations are placed for and used a conservative approach, just skipping them totally.
The real final proof is to compile the same program on two machines and compare.
Edited: seems like me and dELTA likes to post the same thing at same time ^_^
Shub-nigurrath
March 6th, 2008, 11:43
A thing I don't understand is why I cannot debug the linker with a Ring3 debugger..
Daniel Pistelli
March 6th, 2008, 12:02
Try...
See for yourself.
If you manage to do it, good for you! =)
EDIT: ok maybe I haven't been clear about this. In theory it's possible, but first of all you have to recreate a working command line with all the libs etc. And that's something. Then you have to set the right environment, if you just try and run one of the tools in the bin directory it tells you that a dll is missing. You can take the dll from the IDE directory and place it in the folder but it's all horrible. Attaching the ring 3 debugger during execution time doesn't work at all, I can guarantee that. Using softice was just like paradise.
dELTA
March 7th, 2008, 03:52
A little clarification about what Daniel is trying to say:
The real problem with a "ring 3 debugger" in this case is that it does not normally trivially set system wide breakpoints, and since the linker is invoked in the background by Visual Studio (and also has a longish command-line and inherits and makes use of environment info from the parent process etc) and also only lives for a very short moment, the problem is to either catch it just as it is being started this way, or to emulate all these somewhat complex conditions when starting it stand-alone.
So, it's not really the "ring 0" aspect that's wanted, but rather the system wide breakpoint aspect, or actually, rather just the ability to catch this background process on the fly in an efficient way, for which system wide breakpoints is one efficient method.
How about the old spinning jump trick though, shouldn't that work pretty well? Did you try that Daniel? Is that perhaps what you mean by "attaching during execution", and in that case it is a little interesting why it wouldn't work?
Shub-nigurrath
March 7th, 2008, 05:56
I understand. I was thinking about some strange linking time optimizations involving drivers and things like that and was at all sounding strange. Now's clear, of course sice is handy. BTW the spinning jmp trick is the thing I would try for first, if I had time of course..-sigh-
Daniel Pistelli
March 7th, 2008, 07:03
Quote:
How about the old spinning jump trick though, shouldn't that work pretty well? Did you try that Daniel? Is that perhaps what you mean by "attaching during execution", and in that case it is a little interesting why it wouldn't work? |
Oh yes. Of course, I tried that too. Doesn't work the process gets terminated. I guess by another thread which is checking the execution flow or the IDE. I don't knwo.
Thanks for clarifying what I was trying to say, dELTA!
naides
March 7th, 2008, 07:41
A lazy man's trick:
For capturing complex command-line stuff I have used in similar situations
If you have Russinovich Process Explorer running in the background, you can catch the linker process being created and run in the background, as a child process of Visual C or whoever spawns it. If you right click on it and choose properties, you get, among other things, the command line in all its glory, that you can copy and paste for whatever use you please. If the Linker's lifetime is too short for you to "catch" it in Process Explorer, you can change the Proc-Explorer highlight duration option so that those lighting disappearing processes (This is conceived to catch sneaky malware processes usually) are kept visible and highlighted for 10 to 20 seconds after the process has finished, with all its plethora of information, including the folder where the executable is located, as well as the command line, available.
Daniel Pistelli
March 7th, 2008, 08:01
Well, I could've debugger the IDE to get the command line, but still I wouldn't have the environmnet set up for the linker. It's a nice trick yours, but in the end command line + environment settings is just too much work. A system wide breakpoint was an immediate solution. If only I hadn't had VM problems on Vista64.
Thanks for sharing.
klks84
March 7th, 2008, 08:38
If your using VS2005, it comes with "Visual Studio 2005 Command Prompt" which sets the env variables. Also in VS2005, the linker/compiler command line listing for a project/solution can be seen from Project->Properties->Configuration Properties->(C/C++ or Linker)->Command Line
Daniel Pistelli
March 7th, 2008, 09:36
Didn't even remember there was a command prompt. I used the command prompt only with DDK which currently I don't have on my computer (otherwise I would have used that). I got the command line from the properties as you said, but as I didn't have the environment set I thought the command line was incomplete. Of course, it works with the environmnet set. But still, we get back to the main issue, I have to attach myself to the executed process, this time by cmd.exe (the command prompt of Visual Studio) rather than the IDE. It's just the same. Ok, maybe I am just lazy and never got used to work with ollydbg, but if the solution is the command prompt I could've used the IDE in the first place to run the linker.
I am sure there is a way to attach myself to the process created by the IDE or the prompt, I was just too lazy to look it up. And with softice it took me 1 second to break into the linker's code.
Anyway, good that you remembered us all that VS2005 comes with the command prompt like the DDK. I actually put the damn missing dll into the folder to run dumpbin. Now we now how to do that without being as stupid as I have been.
Daniel Pistelli
May 2nd, 2008, 12:06
Update:
http://ntcore.com/Files/richsign.htm
Solved the meaning of @comp.id. It's just the compiler major and minor version.
Just wanted to let you know so that the topic can be closed once and for all.
EDIT:
To make things easier, I wrote a little script to correctly display the data contained in the Rich Signature. Here's a little screen shot of the script's output:
http://ntcore.com/Files/richsign/richdisplay.jpg
Admiral
May 3rd, 2008, 12:02
Edit: I'm a little late to the party, but with regard to the business of attaching to the secondary instance of link.exe:
If I understand the problem correctly, this is more of a problem with OllyDbg than anything else. Olly choses to DEBUG_ONLY_THIS_PROCESS, so you're somewhat screwed when devenv.exe launches the linker. But if you were to use WinDbg with 'Debug child processes also' selected (in the 'Open Executable' dialog), it will automatically attach to all descendent processes, and even be kind enough to break as soon as the new process is created, provided you set the event filters accordingly.
blabberer
May 3rd, 2008, 12:22
well if thats the problem one could simply compile and link seperately isnt it
cl -c blah.c
link blah.obj
Daniel Pistelli
May 3rd, 2008, 12:28
blabberer: actually your suggestion wouldn't work, since that way you won't have the environmnet set for the compiler. We already went in this thread through the VS Prompt approach.
Admiral is right about his solution and it's really time to start using windbg again. I used it to debug device drivers, but as some years have passed I forgot most of the how-to. Somehow softice was deeply buried in memory and I've been glad to use it again, maybe (who knows) for the last time.
blabberer
May 3rd, 2008, 14:11
dunno never much played with vs vc ides and its property thingies
but with plain command line and bcc ive stepped through compilers
just to see if i can still do it
i opened up ollydbg
Log data, item 13
Message=Console file 'E:\Borland\BCC55\Bin\bcc32.exe'
Log data, item 12
Message=Arguments 'blah.c'
runtraced the whole compiler process and logged it to a file 62020 kb long
trapped it on createprocess of ilink32
Code:
0012FD84 0012FE18 |ModuleFileName = "E:\Borland\BCC55\Bin\ilink32.exe"
0012FD88 009528FC |CommandLine = "ilink32.exe @turboc.$ln"
0012FD8C 0012FE0C |pProcessSecurity = 0012FE0C
0012FD90 0012FE0C |pThreadSecurity = 0012FE0C
0012FD94 00000001 |InheritHandles = TRUE
0012FD98 00000000 |CreationFlags = 0
0012FD9C 00000000 |pEnvironment = NULL
0012FDA0 00000000 |CurrentDir = NULL
0012FDA4 0012FDC8 |pStartupInfo = 0012FDC8
0012FDA8 0012FDB8 \pProcessInfo = 0012FDB8
found whats the command line thats getting invoked from the temp file
Code:
E:\borland\bcc55\lib\c0x32.obj+
blah.obj
blah.exe
/Gn/L"E:\borland\bcc55\lib\"/c/x/ap/Tpe
E:\borland\bcc55\lib\import32.lib+
E:\borland\bcc55\lib\cw32.lib
spin jumped the ilink32
Code:
left the compiler looping on wait for single object
Handles, item 22
Handle=00000064
Type=Process
Refs= 10.
Access=001F0FFF SYNCHRONIZE|WRITE_OWNER|WRITE_DAC|READ_CONTROL|DELETE|QUERY_STATE|MODIFY_STATE|FFC
0012FDA0 0049FC7C /CALL to WaitForSingleObject from bcc32.0049FC77
0012FDA4 00000064 |hObject = 00000064
0012FDA8 FFFFFFFF \Timeout = INFINITE
here is a call stack
Code:
Call stack of main thread
Address Stack Procedure / arguments Called from Frame
0012FDA0 0049FC7C <JMP.&KERNEL32.WaitForSingleObject> bcc32.0049FC77 0012FF28
0012FDA4 00000064 hObject = 00000064
0012FDA8 FFFFFFFF Timeout = INFINITE
0012FF2C 0049F538 bcc32.0049F978 bcc32.0049F533 0012FF28
0012FF30 00000000 Arg1 = 00000000
0012FF34 004A31FA Arg2 = 004A31FA ASCII "ilink32.exe"
0012FF38 0012FF54 Arg3 = 0012FF54
0012FF3C 00000000 Arg4 = 00000000
0012FF40 00000001 Arg5 = 00000001
0012FF48 00401794 bcc32.0049F520 bcc32.0040178F 0012FF44
0012FF4C 00000000 Arg1 = 00000000
0012FF50 004A31FA Arg2 = 004A31FA ASCII "ilink32.exe"
0012FF54 004A31FA Arg3 = 004A31FA ASCII "ilink32.exe"
0012FF58 004A3206 Arg4 = 004A3206 ASCII " @turboc.$ln"
0012FF5C 00000000 Arg5 = 00000000
0012FF70 004016E6 bcc32.00401738 bcc32.004016E1
attached another instance of ollydbg to the infinitely spinning ilink32
00401000 >-EB FE JMP SHORT ilink32.<ModuleEntryPoint>
runtraced through the linker process and logged it for an hour
and got an 850 mb log file
Directory of E:\Borland\BCC55\Bin
05/03/2008 11:27 PM 63,507,544 rtrace.txt
05/04/2008 12:27 AM 833,661,462 rtracelink.txt
2 File(s) 897,169,006 bytes
0 Dir(s) 10,716,741,632 bytes free
the linker finished its job in one hour
and i hit my break point at compiler
Log data, item 0
Address=0049FC7C
Message=Breakpoint at bcc32.0049FC7C
Code:
0049FC6E PUSH -1 ; /Timeout = INFINITE; Case 0 of switch 0049FC5C
0049FC70 MOV EDX,DWORD PTR SS:[EBP-170] ; |
0049FC76 PUSH EDX ; |hObject
0049FC77 CALL <JMP.&KERNEL32.WaitForSingleObject> ; \WaitForSingleObject
0049FC7C LEA ECX,DWORD PTR SS:[EBP-4]
saw what is the exit code for the newly created process
Code:
0012FDA0 0049FC8C /CALL to GetExitCodeProcess from bcc32.0049FC87
0012FDA4 00000064 |hProcess = 00000064
0012FDA8 0012FF24 \pExitCode = 0012FF24
let it delete the lnk file after checking var Do_NOT_DELETE_LNK_FILE
Code:
0012FF60 0049B528 /CALL to DeleteFileA from bcc32.0049B523
0012FF64 004A3208 \FileName = "turboc.$ln"
and let the compiler die
it had created a blah.exe which greets you
Code:
Directory of E:\Borland\BCC55\Bin
05/03/2008 11:26 PM 97 blah.c
05/03/2008 11:39 PM 480 blah.obj
05/04/2008 12:26 AM 52,224 blah.exe
05/04/2008 12:26 AM 393,216 blah.tds
4 File(s) 446,017 bytes
0 Dir(s) 10,716,749,824 bytes free
E:\Borland\BCC55\Bin>blah.exe
hello Daniel Pistelli
E:\Borland\BCC55\Bin>
Daniel Pistelli
May 3rd, 2008, 15:13
The compiler of the visual studio needs certain environmnet variables set, that's why the direct cl bla.c approach won't work. Your procedure could be use when compiling through the VS prompt, but it takes certainly longer than just setting a system wide breakpoint or the very clean solution suggested by Admiral (which is certainly better than my one, as long as one remembers how to use windbg). Anyway, any method is imho valid as long as the job gets done.
I'm a bit surprised that dELTA hasn't posted yet. He surely is interested in the latest findings which close the rich signature topic once and for all.
dELTA
May 4th, 2008, 04:44
Hehe, been busy with some RL stuff yesterday.

Nice work indeed Daniel, very interesting as always.

hnedka
January 12th, 2009, 03:22
Quote:
[Originally Posted by Daniel Pistelli;74414]The compiler of the visual studio needs certain environmnet variables set, that's why the direct cl bla.c approach won't work. Your procedure could be use when compiling through the VS prompt, but it takes certainly longer than just setting a system wide breakpoint or the very clean solution suggested by Admiral (which is certainly better than my one, as long as one remembers how to use windbg). Anyway, any method is imho valid as long as the job gets done.
I'm a bit surprised that dELTA hasn't posted yet. He surely is interested in the latest findings which close the rich signature topic once and for all. |
Have you tried debugging linker with Visual Studio ring-3 debugger? It works

You just need to patch exe where you want to break, set VS as just-in-time debugger and when you rebuild some project, it breaks. Press F10 and you are in the code just after the "breakpoint". And it's perfectly traceable. The only problem is that the SEH messes with registers, so you need to deal with this problem. It's also possible to break in Olly (using this method), but you can't trace, only check memory and registers.
EDIT: OK, it's not so easy and more buggy than I first thought, but still possible. But I found a better way - Olly. Put manually breakpoint, rebuild project in VS, Olly breaks. Now open Process Explorer and kill both parent processes of linker and Olly. And now Olly can trace :-). I've run "run trace" and program exited without error after 6000000 commands, so it definitely works and is a solution. Also, Olly 2 beta can trace without killing those two processes, but program exits incorrectly after some time.
blabberer
July 31st, 2011, 23:20
I am Sorry to awaken a Sleeping Giant
But recently i was wanting to run through the linker again

to see who sets the pe header at Pe+0x3c (there is a difference of 0x18 bytes in vc2008) in pe header started at 0xb0
now it is atr 0xc8
Quote:
http://www.woodmann.com/forum/showthread.php?14423-Reconstruct-PE-file-from-process-memory-(and-save-to-disk)
|
so i fired up ollydbg again and this topic of not being able to step through in ollydbg for cbbuildprodid was awakened so i thought let me check
it seems ollydbg can easily step through the code in linker
all you need is this
Code:
Daniel_Pistelli:\>dir /b /a
compile.bat
frizz.c
frizz.obj
linking.bat
Daniel_Pistelli:\>type compile.bat
del frizz.exe & del frizz.obj
"c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat" & cl /c /O1
frizz.c
Daniel_Pistelli:\>type linking.bat
f:\odbg110\ollydbg cmd /c "link /ENTRY:WinMain C:\Docume~1\Admin\Desktop\vc2008~
1\frizz\frizz.obj C:\Progra~1\MI2578~1\Windows\v7.1\Lib\user32.lib C:\Progra~1
\MI2578~1\Windows\v7.1\Lib\kernel32.lib"
Daniel_Pistelli:\>type frizz.c
#include <windows.h>
__declspec(align(1)) char Msg[] = "Iczelion's tutorial no.2";
__declspec(align(1)) char Title[] = "Win32 Assembly is Great!";
__declspec(naked) int WINAPI WinMain( HINSTANCE hIstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
)
{
__asm
{
push MB_OK
push OFFSET Msg
push OFFSET Title
push 0
call MsgBox
push 0
call ExitProc
MsgBox:
jmp dword ptr [MessageBox]
Exitproc:
jmp dword ptr [ExitProcess]
}
}
Daniel_Pistelli:\>
and the plugin modified commandline plugin By anonymouse with Childdbg functionality
just hit alt +f1
type childdbg 1
and hit f9 to land in
004A2249|. E8 D2B3FDFF CALL link.wmain
you can trace through the whole procedure
0046CA74| E8 079EFFFF CALL link.IMAGE::CbBuildProdidBlock; \IMAGE::CbBuildProdidBlock
Code:
Call stack of main thread
Address Stack Procedure / arguments Called from Frame
0013EEF4 0046CA79 link.IMAGE::CbBuildProdidBlock link.IMAGE::BuildImage+1154 0013F380
0013EEF8 011F5D00 Arg1 = 011F5D00
0013EEFC 0013EF7C Arg2 = 0013EF7C
0013F384 004731E8 link.IMAGE::BuildImage link.004731E3 0013F380
0013F7E0 0047DAEB Maybe link.00472822 link.0047DAE9 0013F7DC
0013F7E4 00000005 Arg1 = 00000005
0013F7E8 003C4E58 Arg2 = 003C4E58 ASCII "pN<"
0013FF80 004A224E link.wmain link.__tmainCRTStartup+10A 0013FF7C
0114CD98 21 74 82 CF 65 15 EC 9C 65 15 EC 9C 65 15 EC 9C !t��e�e�e�
0114CDA8 6C 6D 7F 9C 60 15 EC 9C 65 15 ED 9C 67 15 EC 9C lm�`�e�g�
0114CDB8 6C 6D 6F 9C 64 15 EC 9C 6C 6D 7D 9C 64 15 EC 9C lmo�d�lm}�d�
0114CDC8 52 69 63 68 65 15 EC 9C 00 00 00 00 00 00 00 00 Riche�........
0013EEF4 0046CA79 RETURN to link.IMAGE::BuildImage+1159 from link.IMAGE::CbBuildProdidBlock
004668B5 |. C740 04 09789100 MOV DWORD PTR DS:[EAX+4], 917809 changed
00466A96 |. C706 52696368 MOV DWORD PTR DS:[ESI], 68636952
00466A96 C7 06 52 69 63 68 �Rich
Well let This Giant Sleep Again
I am yet to find why Pe header is Starting at oxc8 instead of 0xb0 and
also still have to find who Decides on the Case Of Import Library and the hints on imports
Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.