#How do I detect if a windows executable has defined main or _wmain?

1 messages · Page 1 of 1 (latest)

manic flume
#

this is done for bug hunting obviously. main has horrible issues and I am looking for a programmatic way to check how exactly the program starts running.

sleek horizonBOT
#

When your question is answered use !solved or the button below to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

errant scroll
#

I wonder whether one can access the call stack in c++, and whether that helps in figuring out the name of the main function

#

Anyway, you might want to take a look at <stacktrace>

manic flume
manic flume
errant scroll
#

Ah, that's out of my scope. Sorry

abstract viper
#

the Optional header at offset 68 contains a 2-byte subsystem field which will be 3 for terminal apps and 2 for GUI ones

#

supposedly

abstract viper
foggy thunder
abstract viper
#

ohh

#

yeah idk then

left spruce
#

look at the imports, if those are ansi then it's not unicode 😄

#

unless the c runtime is builtin statically

manic flume
manic flume
manic flume
# abstract viper tested it with PE Bear and yeah it works
Optional Header Windows-Specific Fields (Image Only)

The next 21 fields are an extension to the COFF optional header format. They contain additional information that is required by the linker and loader in Windows.

so this header here,

68/68
    2
    Subsystem
    The subsystem that is required to run this image. For more information, see Windows Subsystem. 

is this what you meant?

manic flume
#

This program is so
D O P E

manic flume
#

what linker flags do I need?

#
g++.exe -D__DEBUG__ -c main.cpp -o main.o -I"%CppIncludeDir0%" -I"%CppIncludeDir1%" -I"%CppIncludeDir2%" -I"%CppIncludeDir2%\c++" -O0 -g3 -std=c++14  -Wall  -Wextra  -Wpedantic  -Weffc++  -Wvla  -Wshadow  -Wconversion  -Wunused-result  -Wswitch  -Wswitch-default  -Wswitch-enum  -O0   -g3  -march=native  -ftrapv -Wmain

main.cpp:609:15: warning: unused parameter 'argc' [-Wunused-parameter]
 int wmain(int argc, wchar_t** argv)
               ^

main.cpp:609:31: warning: unused parameter 'argv' [-Wunused-parameter]
 int wmain(int argc, wchar_t** argv)
                               ^

g++.exe -D__DEBUG__ main.o -o Project1.exe -L"%LibDir0%" -L"%LibDir1%" -static-libgcc -lpthread

%LibDir1%\libmingw32.a(lib64_libmingw32_a-crt0_c.o): In function `main':
C:\crossdev\src\mingw-w64-v3-git\mingw-w64-crt\crt\crt0_c.c:18: undefined reference to `WinMain'
collect2.exe: error: ld returned 1 exit status
abstract viper
#

sorry

foggy thunder
#

It it doesn't work, tell your mingw version

left spruce
#

Or use a real compiler

foggy thunder
left spruce
#

It's a single pass linker, delay loads are broken, the headers shipped with it are often incomplete

foggy thunder
foggy thunder
left spruce
left spruce
manic flume
#

the culprit was that, the flag is needed not only during the compilation of each translation unit but also during linking

#

so now, let me check with PE Bear

manic flume
manic flume
#

What possible 4-byte values can be written in this pointer Entry Point ?

#

welp, testing some old executables shows me many diffent values for the Entry Point pointer

manic flume
#

okay so with MinGW's objdump.exe I can see that my two hello world programs which have no optimizations and have debug symbols, are showing the function names which hint who is using wmain and who is using main

#

but for opaque third party binaries there's just assembly, no function names no nothing, there are no key C-string literals stored in some section that can leak if wmain or main is used

manic flume
foggy thunder
#

No idea 😛

manic flume
manic flume
# foggy thunder No idea 😛

can ghidra decrypt the assembler and detect the argv conversion magic which main binary runs before main, but wmain doesn't?

iron cedar
#

i think u can check which calls are being made in the entry point, it will eventually call GetCommandLineA/W and WideCharToMultiByte

manic flume
iron cedar
#

there are multiple ways to construct argv from wargv so u likely want to check if such behavior exists

manic flume
#

found one thing in the executable with main defined

#

will keep looking

#

however this thing here applies for console applications only, I need something more generic for GUI programs

#

Nope, even for wmain the same TSAppCompat thing shows GetEnvironmentStringsA, so that's not a deciding factor

#

maybe the compiler optimized out the main args completely, let me print them to force it to use them and retry

manic flume
#

I was so close goddamnit

iron cedar
manic flume
#

its GUI

iron cedar
#

hmm i dont remember that ui angry_thonk

#

are u planning to automate this?

manic flume
manic flume
iron cedar
#

well what i mean is that are u trying to run this check on lots of binaries? or just a few that u can manually analyze

manic flume
manic flume
iron cedar
#

the thing is i cant do that on a phone yamikek

manic flume
#

GET A COMPUTER

manic flume
#

@iron cedar
bump

iron cedar
#

hi

#

do u have ghidra?

manic flume
#

you can grab the C compiler and produce the 2 programs from my snippets above

iron cedar
#

puter broken

manic flume
iron cedar
#

yes

rugged shore
#

Ah forget it I am not gonna read this entire forum

manic flume
manic flume
#

I FOUND THE ANSWER AT LAST

#

So now I need a script to programatically take in an executable name and return, does the library kernel32.dll contain a call to GetStartupInfoA or GetStartupInfoW

iron cedar
#

it also matters where the call is being made and how its used if u want to improve it further

#

do check the result of different crts in a disassembler

#

now that i think about it actually i doubt this is what u really need

left spruce
iron cedar
#

i know, its a reminder to not rely only on the import table

manic flume
#

!solved

sleek horizonBOT
#

Thank you and let us know if you have any more questions!

This thread is now set to auto-hide after an hour of inactivity

manic flume
abstract viper