- Name - flareon2016challenge
- Category - Reverse Engineering
- Points - 4
- Description - n/a
- Binary - Download here
signed int flareon2016challenge_7() { byte_10007014[dword_10007010-- % 0x10u] -= 79; return 16; }And flareon2016challenge_47() looks like this:
signed int flareon2016challenge_47() { char v0; // cl@1 v0 = __ROL1__(byte_10007014[dword_10007010 % 0x10u], 4); byte_10007014[dword_10007010-- % 0x10u] = v0; return 20; }If we chain the return values we get the following: 30 -> 15 -> 42 -> 18 -> ... -> 35 -> 1 -> 51. The only 2 exported functions which are not part of this chain are flareon2016challenge_49() and flareon2016challenge50(). These will come into play later. Lets see what happens when we call the functions in the chain using the C program below:
int main(int argc, char* argv[]) { FARPROC func; HINSTANCE dllHandle = LoadLibraryA("flareon2016challenge.dll"); if (dllHandle == NULL) return 0; // Start from function 30 int next_func = 30; // Go through chain of functions while (1) { printf("Calling function %d\r\n", next_func); func = GetProcAddress(dllHandle, next_func); next_func = func(); if (next_func == 51) { printf("Calling function %d\r\n", next_func); func = GetProcAddress(dllHandle, next_func); func(); break; } printf("Press Any Key to Continue\n"); getchar(); return 0; }The first thing we notice is the following: The most important thing though happens in the function which is called at the end, namely flareon2016challenge_51():
int flareon2016challenge_51() { char v1; // [sp+0h] [bp-90h]@1 sub_10001530(16); sub_10001000((int)&v1, (int)&unk_10007060, (int)&unk_10007060, 6672); return printf(aPlayMeASongHav); }Each of the functions listed above operate on a buffer which, after our program ends, looks like this in memory: Copy the bytes into a hex editor, construct the PE file locally and open it in IDA. The main function only has the following:
int __cdecl main(int argc, const char **argv, const char **envp) { Beep(0x1B8u, 0x1F4u); Beep(0x1B8u, 0x1F4u); Beep(0x1B8u, 0x1F4u); Beep(0x15Du, 0x15Eu); Beep(0x20Bu, 0x96u); Beep(0x1B8u, 0x1F4u); Beep(0x15Du, 0x15Eu); Beep(0x20Bu, 0x96u); Beep(0x1B8u, 0x3E8u); Beep(0x293u, 0x1F4u); Beep(0x293u, 0x1F4u); Beep(0x293u, 0x1F4u); Beep(0x2BAu, 0x15Eu); Beep(0x20Bu, 0x96u); Beep(0x19Fu, 0x1F4u); Beep(0x15Du, 0x15Eu); Beep(0x20Bu, 0x96u); Beep(0x1B8u, 0x3E8u); return 0; }Running the binary plays Darth Vader's theme. Interesting! Let's look at flareon2016challenge_50():
int __cdecl flareon2016challenge_50(DWORD dwFreq, DWORD dwDuration) { int result; // eax@1 Beep(dwFreq, dwDuration); byte_10007028[dword_10008DD4] -= dwFreq; byte_10007028[dword_10008DD4] ^= dwDuration; result = dword_10008DD4++ + 1; if ( dword_10008DD4 == 18 ) result = flareon2016challenge_49(); return result; }The function accepts 2 variables: dwFreq and dwDuration, just like the Beep() function in the extracted PE. Let's feed these into this function using the following program:
int main(int argc, char* argv[]) { FARPROC func; HINSTANCE dllHandle = LoadLibraryA("flareon2016challenge.dll"); if (dllHandle == NULL) return 0; // call flareon2016challenge_50 18 times for Darth Vader song func = GetProcAddress(dllHandle, 50); func(440, 500); func(440, 500); func(440, 500); func(349, 350); func(523, 150); func(440, 500); func(349, 350); func(523, 150); func(440, 1000); func(659, 500); func(659, 500); func(659, 500); func(698, 350); func(523, 150); func(415, 500); func(349, 350); func(523, 150); func(440, 1000); printf("Press Any Key to Continue\n"); getchar(); return 0; }After Darth Vader's theme we get:
Command Prompt
C:\>solver.exe
f0ll0w_t3h_3xp0rts@flare-on.com
Press Any Key to Continue
_
No comments:
Post a Comment