Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
printf.printf(char*,...);
#include <stdio.h>
push -11
call GetStdHandle
extern _ExitProcess@4, _GetStdHandle@4, _WriteConsoleA@20
%define ExitProcess _ExitProcess@4
%define GetStdHandle _GetStdHandle@4
%define WriteConsoleA _WriteConsoleA@20
global _main
section .data
msg db "Hello World!", 13, 10, 0
msg.len equ $ - msg
section .text
_main:
push -11
call GetStdHandle
push 0
push 0
push msg.len
push msg
push eax
call WriteConsoleA
push 0
call ExitProcess
nasm hw.asm -f win32 -o hw.obj && link hw.obj /out:hw.exe /entry:main /defaultlib:kernel32
__asm {
xor edi, edi
push 0x0021646C
push 0x726F5720
push 0x2C6F6C6C
push 0x65480000
lea eax, [esp + 2]
push edi
push edi
mov ebx, esp
push 13
push eax
push ebx ; output pointer to IoStatusBlock, does not matter if we overrite some data in stack
push edi
push edi
push edi
; get output file handler from TEB/PEB
mov eax, fs:[030h]
mov eax, [eax+10h]
mov eax, [eax+1Ch]
push eax
push 0 ; ret addr, skipped by syscall handler
; call func
mov eax, 1A0007h ; NtWriteFile, check syscall # for your windows version
call fs:[0C0h]
add esp, 38h ; 10h string + 24h syscall stack + 4h ret
}
NTSTATUS ZwWriteFile(
_In_ HANDLE FileHandle,
_In_opt_ HANDLE Event,
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcContext,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ PVOID Buffer,
_In_ ULONG Length,
_In_opt_ PLARGE_INTEGER ByteOffset,
_In_opt_ PULONG Key
);
#include <stdio.h>
#include <intrin.h>
int main()
{
printf("%08x\n", ((int**)__readfsdword(0x30))[0x10/4][0x1C/4]);
return 0;
}
C:\> test | more
0000006C
C:\> test
0000000F

#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
int main()
{
uintptr_t offset = 0x71;
size_t pagesize = sysconf( _SC_PAGESIZE );
char* m = (char*)&main;
uintptr_t pagestart = ( (uintptr_t)m ) & -pagesize;
mprotect( (void*)pagestart, ( (uintptr_t)m ) - pagestart + offset, PROT_READ | PROT_WRITE | PROT_EXEC );
m[offset] = 'e';
printf( "H%cllo World!\n", 'a' );
}
За изобретение ставлю пять, а… по предмету — неуд
Конечно подобные договора не стоит заключать, но иногда выхода нетЛибо я ничего не понимаю, либо одно из двух.
#pragma comment(linker, "/NODEFAULTLIB")
#pragma comment(linker, "/FILEALIGN:16")
#pragma comment(linker, "/ALIGN:16")// Merge sections
#pragma comment(linker, "/MERGE:.rdata=.data")
#pragma comment(linker, "/MERGE:.text=.data")
#pragma comment(linker, "/MERGE:.reloc=.data")
// Favour small code
#pragma optimize("gsy", on)
#pragma comment(linker, "/FILEALIGN:16")
#pragma comment(linker, "/ALIGN:16")// Merge sections
Раньше можно покороче сделать было байт-код.
Ой, а я почему-то думал, что дизассемблер в фугкции собирает, типа программу на си выдает, которая компилируется в такой же ассемблерный код
с чем автор в итоге поигрался
MouseData:
DATA 55,89,E5,8B,5E,0C,8B,07,50,8B,5E,0A,8B,07,50,8B
DATA 5E,08,8B,0F,8B,5E,06,8B,17,5B,58,1E,07,CD,33,53
DATA 8B,5E,0C,89,07,58,8B,5E,0A,89,07,8B,5E,08,89,0F
DATA 8B,5E,06,89,17,5D,CA,08,00
...
SUB MouseDriver (Ax, Bx, Cx, Dx)
DEF SEG = VARSEG(Mouse$)
Mouse = SADD(Mouse$)
CALL Absolute(Ax, Bx, Cx, Dx, Mouse)
END SUB
link /OUT:dummy.exe /SUBSYSTEM:CONSOLE /ENTRY:ExitProcess@4 kernel32.lib





#pragma section(".exre", execute, read)
__declspec(allocate(".exre")) int main[] = {
0x0a0d2168, 0x726f6800, 0x6f68646c, 0x6857202c,
0x6c6c6548, 0x6a54006a, 0x0483540d, 0xd2330c24,
0x30528b64, 0xff10428b, 0x8bfc1c70, 0x528b0c52,
0x28728b14, 0x000018b9, 0x33ff3300, 0x613cacc0,
0x202c027c, 0x030dcfc1, 0x8bf2e2f8, 0xff81105a,
0x6a4abc5b, 0xd975128b, 0x8b555756, 0x6c8b3c53,
0xeb037813, 0x8b184d8b, 0xfb03207d, 0x8b4933e3,
0xf3038f34, 0xd233c033, 0x74c43aac, 0x0dcac107,
0xf4ebd003, 0x791ffa81, 0xe075e80a, 0x0324558b,
0x0c8b66d3, 0x1c558b4a, 0x048bd303, 0xebc3038a,
0x5f5dcc01, 0x83d0ff5e, 0xc310c4};
Проверял на Windows 7.repe cmpsb занимает всего два байта.#pragma section(".exre", execute, read)
__declspec(allocate(".exre")) int main[] = {
0x0a0d2168, 0x726f6800, 0x6f68646c, 0x6857202c,
0x6c6c6548, 0x6a54006a, 0x0483540d, 0xd2330c24,
0x30528b64, 0xff10428b, 0x8bfc1c70, 0x528b0c52,
0x28728b14, 0x000018b9, 0x33ff3300, 0x613cacc0,
0x202c027c, 0x030dcfc1, 0x8bf2e2f8, 0xff81105a,
0x6a4abc5b, 0xd975128b, 0x6a555756, 0x46656865,
0x57686c69, 0x8b746972, 0x6c8b3c53, 0xeb037813,
0x8b18558b, 0xc3032045, 0x90348b4a, 0x0ab9f303,
0x8b000000, 0x75a6f3fc, 0x24458bef, 0x8b66c303,
0x458b500c, 0x8bc3031c, 0xc3039004, 0x5d0cc483,
0xd0ff5e5f, 0xc310c483 };
Я просто высказал предположение, на глаз, что судя по длине, используется простая хэш-функция.
Чтобы запускалось на x86, /FILEALIGN должен быть как минимум 512, т.е. все заголовки вместе взятые меньше чем 512 байт занимать не могут.
4 + sizeof(IMAGE_NT_HEADERS64)). И если «не стесняться кромсать всё, что создал компилятор» и вообще делать PE-файл руками, то такой файл сделать можно: code.google.com/archive/p/corkami/wikis/PE.wiki, «universal tiny PE» (там есть ссылка «nightly builds», ведущая на dropbox, в котором есть архив pe.rar, в котором есть файл tiny.exe). Он выводит строку " * 268b universal tiny PE" вместо «Hello, World!».4 + sizeof(IMAGE_NT_HEADERS32)).start end module name
00400000 00400104 image00400000 C (no symbols)
7c800000 7c8f6000 kernel32 (deferred)
7c900000 7c9b2000 ntdll (pdb symbols)
«Hello World!» на C массивом int main[]