Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PE linker version

271 views
Skip to first unread message

datx...@yahoo.com

unread,
Jul 21, 2011, 9:55:32 PM7/21/11
to
I need to remove the compiler version information from the PE header
of a bunch of executables.

I have found a number of tools that allow me to tell which compiler
was used but I have not found one that allows me to delete that
information.

Any help would be most appreciated.

datx...@yahoo.com

unread,
Jul 21, 2011, 10:47:13 PM7/21/11
to
Ok.

It is not MajorLinkerVersion or MinorLinkerVersion only.

Apparently the complier also identifies itself somewhere else in the
PE header.

Liviu

unread,
Jul 26, 2011, 2:16:40 AM7/26/11
to
<datx...@yahoo.com> wrote...

>
> It is not MajorLinkerVersion or MinorLinkerVersion only.

No surprise that the compiler wouldn't put its version info under
the linker fields.

> Apparently the complier also identifies itself somewhere else
> in the PE header.

That's a bit more complicated, since a PE has only one header,
but may include objects built with different compilers, or none at all
for that matter.

If you really need to remove _all_ compiler info from the executable,
then get a decent PE editor and delete all sections named ".text" or
marked as "E". To be paranoidly sure, do the same for ".*data" and
"R/W" since sneaky compilers have been known to leave traces in
those sections, too.

;-)


Joseph M. Newcomer

unread,
Jul 26, 2011, 6:31:13 PM7/26/11
to
In reading this, I wonder if the goal is to hide the use of gcc so that no one can request
the source code. If this were true, it would be exceptionally poor business practice,
because the code is sufficiently valuable, then a non-GNU compiler is affordable. It
doesn't necessarily have to be VS.
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Liviu

unread,
Jul 28, 2011, 12:36:53 AM7/28/11
to
"Joseph M. Newcomer" <newc...@flounder.com> wrote...

>
> In reading this, I wonder if the goal is to hide the use of gcc so
> that no one can request the source code.

GCC and its runtime libs can be used to compile and deliver closed
source commercial apps (within common sense, such as not attempting to
resell a recompile of itself, or other silly things along that line).

I won't venture to second guess the reason behind OP's question,
since it displayed such deep confusion between compiler/linker/pe/etc
as to make whatever original motive moot ;-)

Liviu


Joseph M. Newcomer

unread,
Jul 28, 2011, 11:15:58 AM7/28/11
to
I thought there was serious confusion, myself, so I checked using dumbpin ./all the only
suggestion that the Microsoft compiler might have been used was a set of import records
from MSVCR90D.DLL. I didn't see anything else that suggested the compiler that was used.
The reference to the .pdb file might also be suggestive, but not definitive, since any
other compiler/debugger might also use a .pdb file.
joe


Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.


Dump of file XXXXXXX.exe

PE signature found

File Type: EXECUTABLE IMAGE

FILE HEADER VALUES
14C machine (x86)
7 number of sections
4E2FACAB time date stamp Wed Jul 27 02:14:03 2011
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
102 characteristics
Executable
32 bit word machine

OPTIONAL HEADER VALUES
10B magic # (PE32)
9.00 linker version
25A00 size of code
3D400 size of initialized data
0 size of uninitialized data
12C66 entry point (00412C66) @ILT+7265(_wWinMainCRTStartup)
1000 base of code
1000 base of data
400000 image base (00400000 to 00475FFF)
1000 section alignment
200 file alignment
5.00 operating system version
0.00 image version
5.00 subsystem version
0 Win32 version
76000 size of image
400 size of headers
0 checksum
2 subsystem (Windows GUI)
8140 DLL characteristics
Dynamic base
NX compatible
Terminal Server Aware
100000 size of stack reserve
1000 size of stack commit
100000 size of heap reserve
1000 size of heap commit
0 loader flags
10 number of directories
0 [ 0] RVA [size] of Export Directory
43000 [ B4] RVA [size] of Import Directory
46000 [ 2BB29] RVA [size] of Resource Directory
0 [ 0] RVA [size] of Exception Directory
0 [ 0] RVA [size] of Certificates Directory
72000 [ 2E68] RVA [size] of Base Relocation Directory
37AD0 [ 1C] RVA [size] of Debug Directory
0 [ 0] RVA [size] of Architecture Directory
0 [ 0] RVA [size] of Global Pointer Directory
0 [ 0] RVA [size] of Thread Storage Directory
0 [ 0] RVA [size] of Load Configuration Directory
0 [ 0] RVA [size] of Bound Import Directory
44248 [ 1194] RVA [size] of Import Address Table Directory
0 [ 0] RVA [size] of Delay Import Directory
0 [ 0] RVA [size] of COM Descriptor Directory
0 [ 0] RVA [size] of Reserved Directory


SECTION HEADER #1
.textbss name
10000 virtual size
1000 virtual address (00401000 to 00410FFF)
0 size of raw data
0 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
E00000A0 flags
Code
Uninitialized Data
Execute Read Write

SECTION HEADER #2
.text name
2581C virtual size
11000 virtual address (00411000 to 0043681B)
25A00 size of raw data
400 file pointer to raw data (00000400 to 00025DFF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
Execute Read

RAW DATA #2
...borind data omitted

SECTION HEADER #3
.rdata name
9F50 virtual size
37000 virtual address (00437000 to 00440F4F)
A000 size of raw data
25E00 file pointer to raw data (00025E00 to 0002FDFF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
Read Only

RAW DATA #3
...boring data omitted

Debug Directories

Time Type Size RVA Pointer
-------- ------ -------- -------- --------
4E2ED401 cv 3F 0003E5B0 2D3B0 Format: RSDS,
{05CF6715-81E4-494B-811A-42029740456A}, 46, i:\testsXXXXXXX\Debug\XXXXXXXX.pdb

SECTION HEADER #4
.data name
1020 virtual size
41000 virtual address (00441000 to 0044201F)
A00 size of raw data
2FE00 file pointer to raw data (0002FE00 to 000307FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
Read Write

RAW DATA #4
...boring data omitted

SECTION HEADER #5
.idata name
2DE4 virtual size
43000 virtual address (00443000 to 00445DE3)
2E00 size of raw data
30800 file pointer to raw data (00030800 to 000335FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
Read Write

RAW DATA #5
...boring data omitted

Section contains the following imports:

mfc90ud.dll
4445DC Import Address Table
443448 Import Name Table
0 time date stamp
0 Index of first forwarder reference

Ordinal 6487
...long list of ordinals omitted
Ordinal 2987

MSVCR90D.dll
4443EC Import Address Table
443258 Import Name Table
0 time date stamp
0 Index of first forwarder reference

...import records omitted
KERNEL32.dll
4442E4 Import Address Table
443150 Import Name Table
0 time date stamp
0 Index of first forwarder reference

...import records omitted
USER32.dll
444560 Import Address Table
4433CC Import Name Table
0 time date stamp
0 Index of first forwarder reference

...import records omitted

GDI32.dll
4442B0 Import Address Table
44311C Import Name Table
0 time date stamp
0 Index of first forwarder reference

1F4 GetStockObject
D0 DeleteObject
160 GdiFlush

COMCTL32.dll
444280 Import Address Table
4430EC Import Name Table
0 time date stamp
0 Index of first forwarder reference

7A InitCommonControlsEx

OLEAUT32.dll
444510 Import Address Table
44337C Import Name Table
0 time date stamp
0 Index of first forwarder reference

Ordinal 9
Ordinal 6
Ordinal 200
Ordinal 12
Ordinal 8
Ordinal 202
Ordinal 2
Ordinal 201

ADVAPI32.dll
444248 Import Address Table
4430B4 Import Name Table
0 time date stamp
0 Index of first forwarder reference

28A RevertToSelf
1F6 OpenThreadToken
2BB SetThreadToken

SECTION HEADER #6
.rsrc name
2BB29 virtual size
46000 virtual address (00446000 to 00471B28)
2BC00 size of raw data
33600 file pointer to raw data (00033600 to 0005F1FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
Read Only

RAW DATA #6
...boring data omitted

SECTION HEADER #7
.reloc name
3636 virtual size
72000 virtual address (00472000 to 00475635)
3800 size of raw data
5F200 file pointer to raw data (0005F200 to 000629FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
42000040 flags
Initialized Data
Discardable
Read Only

RAW DATA #7
...boring data omitted

BASE RELOCATIONS #7
...boring relocations omitted
Summary

2000 .data
3000 .idata
A000 .rdata
4000 .reloc
2C000 .rsrc
26000 .text
10000 .textbss

So I'm not sure where the OP is seeing this magical information.
joe

Liviu

unread,
Jul 28, 2011, 11:40:33 PM7/28/11
to
"Joseph M. Newcomer" <newc...@flounder.com> wrote...
>
> I thought there was serious confusion, myself, so I checked using
> dumbpin ./all the only suggestion that the Microsoft compiler might
> have been used was a set of import records from MSVCR90D.DLL.

That's a tell-tale sign, indeed, but even that is not absolute. For
example the MinGW gcc links to MSVCRT but it's certainly not
built with a MS compiler itself.

My guess is that the OP has come across some PE tool claiming to
second guess "the compiler" and did not realize that _the_ compiler
is a hopelessly wrong target to chase at the PE level, as opposed to
object level. I've had PEs made of C++ modules compiled with MSVC,
numerical libraries compiled with ICL and the accidental assembler shim.
It's anybody's guess what one of those wonder PE tools would report as
_the_ compiler in such cases ;-)

Liviu


Joseph M. Newcomer

unread,
Jul 29, 2011, 2:16:11 AM7/29/11
to
Someone who is familiar with the "idioms" of a particular compiler might, just might, be
able to analyze the code patterns and guess what compiler was used. However, only
optimized code tends to exhibit such characteristics, because only the optimizers make
characteristic transformations. Similarly, you can frequently tell when an assembly-code
module is included, because it uses instructions and idioms no compiler would ever use.
But it takes years of experience across multiple compilers to build this recognition.
Since the only C compiler I've used in the last 20 years is one of the compilers from
Microsoft, I really don't know what the gcc, Intel, etc. idioms are. I suspect a really
powerful "AI" recognizer might have a chance. I can usually tell an assembler module
because its patterns are uncharacteristic of what I know the C/C++ compiler produces. But
beyond that, I don't have the experience in competing compilers to tell the difference.

It is not clear that even if you have the .obj files, you can specifically tell what
compiler generated it (without looking at the code patterns). I looked at a dumpbin of a
.obj file, and nothing really jumped out and said "I was created by the Microsoft
compiler" (there's a reason it is called COFF - "Common Object File Format"--which is that
all compilers generate it, so they interoperate). Again, perhaps someone who studied the
COFF output from several compilers might recognize some idioms, but of course this
information is discarded by the time the .exe file is generated.
joe

Kira Qian

unread,
Jul 29, 2011, 3:26:52 AM7/29/11
to
Once a execute file is generated, there is no way to reverse it or edit with existed API. I think your question is how to write a program to edit a bunch of PE file. I think you can't. For a single PE file, you can try PE Explorer.

Joseph M. Newcomer

unread,
Jul 29, 2011, 5:26:24 PM7/29/11
to
Well, if you want to be strict about it, yes, the standard APIs work. They are
CreateFile, ReadFile and WriteFile. I know what you meant, but it isn't exactly what you
said.
joe

On Fri, 29 Jul 2011 00:26:52 -0700 (PDT), Kira Qian <kira...@gmail.com> wrote:

>Once a execute file is generated, there is no way to reverse it or edit with existed API. I think your question is how to write a program to edit a bunch of PE file. I think you can't. For a single PE file, you can try PE Explorer.

datx...@yahoo.com

unread,
Aug 2, 2011, 4:27:49 AM8/2/11
to
Thank you, everyone, for the replies.
0 new messages