Hello, World!
-------------
ello, World!
------------
llo, World!
-----------
lo, World!
----------
o, World!
---------
, World!
--------
World!
-------
World!
------
orld!
-----
rld!
----
ld!
---
d!
--
!
-
If we are given a binary compiled from that source and we want to figure out how the source looks, we can use a decompiler to get c pseudocode which we can then use to reconstruct the function. The sample decompilation can look like:
printSpacer:
int __fastcall printSpacer(int a1)
{
int i; // [rsp+8h] [rbp-8h]
for ( i = 0; i < a1; ++i )
printf("-");
return printf("\n");
}
main:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+18h] [rbp-18h]
signed int i; // [rsp+1Ch] [rbp-14h]
for ( i = 0; i < 13; ++i )
{
v4 = i + 1;
printf("%c", (unsigned int)aHelloWorld[i], envp);
while ( v4 < 13 )
printf("%c", (unsigned int)aHelloWorld[v4++]);
printf("\n");
printSpacer(13 - i);
}
return 0;
}
A good method of getting a good representation of the source is to convert the decompilation into Python since Python is basically psuedocode that runs. Starting with main often allows you to gain a good overview of what the program is doing and will help you translate the other functions.
Main
We know we will start with a main function and some variables, if you trace the execution of the variables, you can oftentimes determine the variable type. Because i
is being used as an index, we know its an int, and because v4
used as one later on, it too is an index. We can also see that we have a variable aHelloWorld
being printed with %c
, we can determine it represents the 'Hello, World!'
string. Lets define all these variables in our Python main function:
def main():
string = "Hello, World!"
i = 0
v4 = 0
for i in range(0, 13):
v4 = i + 1
print(string[i], end='')
while v4 < 13:
print(string[v4], end='')
v4 += 1
print()
printSpacer(13-i)