-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
217 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
*.o | ||
*.kex | ||
*.exe | ||
*.com | ||
/*.c | ||
/.vscode/* | ||
/.vs/* | ||
/*.exe | ||
/test/*.exe | ||
/test/*.com | ||
/test/*.kex | ||
/test/*.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
format PE console | ||
entry start | ||
|
||
section '.idata' import data readable writeable | ||
|
||
dd 0,0,0,RVA kernel_name,RVA kernel_table | ||
dd 0,0,0,RVA crt_name,RVA crt_table | ||
dd 0,0,0,0,0 | ||
|
||
kernel_table: | ||
ExitProcess dd RVA _ExitProcess | ||
GetProcessHeap dd RVA _GetProcessHeap | ||
HeapAlloc dd RVA _HeapAlloc | ||
dd 0 | ||
crt_table: | ||
putchar dd RVA _putchar | ||
getchar dd RVA _getchar | ||
dd 0 | ||
|
||
kernel_name db 'KERNEL32.DLL',0 | ||
crt_name db 'MSVCRT.DLL',0 | ||
|
||
_ExitProcess dw 0 | ||
db 'ExitProcess',0 | ||
_HeapAlloc dw 0 | ||
db 'HeapAlloc',0 | ||
_GetProcessHeap dw 0 | ||
db 'GetProcessHeap',0 | ||
_putchar dw 0 | ||
db 'putchar', 0 | ||
_getchar dw 0 | ||
db '_getch', 0 | ||
|
||
section '.text' code readable executable | ||
|
||
bf_putchar: | ||
push eax | ||
push ebx | ||
push ecx | ||
push dword[eax] | ||
call [putchar] | ||
add esp, 4 | ||
pop ecx | ||
pop ebx | ||
pop eax | ||
ret | ||
|
||
bf_getchar: | ||
push ebx | ||
push ecx | ||
push eax | ||
call [getchar] | ||
mov ebx, eax | ||
pop eax | ||
mov byte[eax], bl | ||
pop ecx | ||
pop ebx | ||
ret | ||
|
||
start: | ||
|
||
call [GetProcessHeap] | ||
push 30000 | ||
push 8 | ||
push eax | ||
call [HeapAlloc] | ||
mov ebx, bf_putchar | ||
mov ecx, bf_getchar | ||
call brainfuck | ||
push 0 | ||
call [ExitProcess] | ||
brainfuck: | ||
db "PLACE_FOR_BRAINFUCK_CODE" |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#include <obfmc.h> | ||
|
||
unsigned aligned(unsigned n, int align) { | ||
return (n + align-1) & ~(align-1); | ||
} | ||
|
||
int getOffsetOfSpecialMark(char *code, char *max) { | ||
int size = 0; | ||
|
||
while (code < max && | ||
memcmp(code, "PLACE_FOR_BRAINFUCK_CODE", strlen("PLACE_FOR_BRAINFUCK_CODE"))) | ||
{ code++; size++; } | ||
if (code >= max) { return 0; } | ||
return size; | ||
} | ||
|
||
//! ACHTUNG: Look at "HARDCODED" achtungs before runtime modification | ||
int buildWin32(Bf *restrict bf, const char *restrict name) { | ||
int errorCode = 0; | ||
int runtimeSize = 0; | ||
int imageSize = 0; | ||
char *image = NULL; | ||
size_t codeSize = 0; | ||
char *code = NULL; | ||
|
||
{ | ||
FILE *runtime = NULL; | ||
|
||
if (!(runtime = fopen("runtime/win32.bin", "rb"))) { return ERROR_CAN_NOT_OPEN_RUNTIME; } | ||
// get size of runtime | ||
fseek(runtime, 0, SEEK_END); | ||
runtimeSize = ftell(runtime); | ||
rewind(runtime); | ||
// get code and its size | ||
if ((errorCode = genI386(bf, &codeSize, &code))) { return errorCode; } | ||
// allocate enough memory for runtime (which is aligned and so have space for our code) | ||
// possilbly (if app code will be large) we will need expand image later | ||
imageSize = runtimeSize; | ||
if (!(image = malloc(imageSize))) { return ERROR_OUT_OF_MEMORY; } | ||
// copy runtime code | ||
fread(image, 1, runtimeSize, runtime); | ||
fclose(runtime); | ||
} | ||
{ | ||
int codeSectionOffset = 0; | ||
int sizeOfRuntimeCode = 0; | ||
int maxCodeInSection = 0; | ||
int codeOffset = 0; | ||
|
||
// check if we need to expand image | ||
codeSectionOffset = *(int *)(image + 0x1b4); //! ACHTUNG: HARDCODED | ||
if (!(sizeOfRuntimeCode = getOffsetOfSpecialMark(image + codeSectionOffset, | ||
image + runtimeSize))) { return ERROR_PLACE_FOR_CODE_NOT_FOUND; } | ||
codeOffset = codeSectionOffset + sizeOfRuntimeCode; | ||
maxCodeInSection = 0x200 - sizeOfRuntimeCode; | ||
// if need - expand it | ||
if (codeSize > maxCodeInSection) { | ||
int additional512ByteParts = 0; | ||
int extraCode = 0; | ||
|
||
extraCode = codeSize - maxCodeInSection; | ||
additional512ByteParts = extraCode / 512 + 1; | ||
// expand image | ||
imageSize += additional512ByteParts * 512; | ||
image = realloc(image, imageSize); | ||
// set up PE file fields | ||
//! FIXME: UB | ||
//! ACHTUNG: hardcoded | ||
if (additional512ByteParts) { | ||
// OptionalHeader::SizeOfCode | ||
*(int *)(image + 0x9c) += additional512ByteParts * 512; | ||
// OptionalHeader::SizeOfImage | ||
*(int *)(image + 0xd0) = 0x2000 + aligned(codeSize + sizeOfRuntimeCode, 0x1000); | ||
// SectionHeader::VirtualSize (.text) | ||
*(int *)(image + 0x1a8) += additional512ByteParts * 512; | ||
// SectionHeader::SizeOfRawDara (.text) | ||
*(int *)(image + 0x1b0) += additional512ByteParts * 512; | ||
} | ||
} | ||
// now we can safely copy brainfuck code | ||
memcpy(image + codeOffset, code, codeSize); | ||
} | ||
// write image to file | ||
{ | ||
char newName[strlen(name) + 5]; | ||
FILE *fp = NULL; | ||
|
||
strcpy(newName, name); | ||
strcat(newName, ".exe"); | ||
fp = fopen(newName, "wb"); | ||
if (!fp) { return ERROR_OUTPUT_FILE_IS_NOT_CREATED; } | ||
fwrite(image, 1, imageSize, fp); | ||
fclose(fp); | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
-,+[ Read first character and start outer character reading loop | ||
-[ Skip forward if character is 0 | ||
>>++++[>++++++++<-] Set up divisor (32) for division loop | ||
(MEMORY LAYOUT: dividend copy remainder divisor quotient zero zero) | ||
<+<-[ Set up dividend (x minus 1) and enter division loop | ||
>+>+>-[>>>] Increase copy and remainder / reduce divisor / Normal case: skip forward | ||
<[[>+<-]>>+>] Special case: move remainder back to divisor and increase quotient | ||
<<<<<- Decrement dividend | ||
] End division loop | ||
]>>>[-]+ End skip loop; zero former divisor and reuse space for a flag | ||
>--[-[<->+++[-]]]<[ Zero that flag unless quotient was 2 or 3; zero quotient; check flag | ||
++++++++++++<[ If flag then set up divisor (13) for second division loop | ||
(MEMORY LAYOUT: zero copy dividend divisor remainder quotient zero zero) | ||
>-[>+>>] Reduce divisor; Normal case: increase remainder | ||
>[+[<+>-]>+>>] Special case: increase remainder / move it back to divisor / increase quotient | ||
<<<<<- Decrease dividend | ||
] End division loop | ||
>>[<+>-] Add remainder back to divisor to get a useful 13 | ||
>[ Skip forward if quotient was 0 | ||
-[ Decrement quotient and skip forward if quotient was 1 | ||
-<<[-]>> Zero quotient and divisor if quotient was 2 | ||
]<<[<<->>-]>> Zero divisor and subtract 13 from copy if quotient was 1 | ||
]<<[<<+>>-] Zero divisor and add 13 to copy if quotient was 0 | ||
] End outer skip loop (jump to here if ((character minus 1)/32) was not 2 or 3) | ||
<[-] Clear remainder from first division if second division was skipped | ||
<.[-] Output ROT13ed character from copy and clear it | ||
<-,+ Read next character | ||
] |