In this case, you will need to edit the character string passed to printf , but first we need to get its address. look at the code for calling printf , we will see something like that:
PUSH mymodule.1234567 CALL printf ADD ESP,4
so if we go to address 0x1234567 , via ctrl + g , we will see:
01234567 48 65 6C 6C 6F 20 57 6F 72 6C 64 0A 00 00 00 00 Hello World.....
Now you can edit this line to whatever you want, until you overflow the available space and save the zero delimiter.
Saving changes depends on how you downloaded the binary (either by attaching or just viewing in cold mode), the easiest way is to view in cold mode (using olly is pure as a disassembler / assembler). Its access is through view -> file then right-click and select disassemble in the context menu. In this mode, saving is performed by right-clicking and selecting save file in the context menu.
In debug mode (for example, when connecting), saving is performed by right-clicking and selecting one of the options from the context menu copy to executable .
Update
If you are debugging the generated GCC code, it usually avoids generating PUSH and prefers pushing variables directly onto the stack using MOV [ESP+c],c/r/m . Compiling your example with GCC, you will see code similar to (for main ):
00401AFC /$ PUSH EBP 00401AFD |. MOV EBP,ESP 00401AFF |. AND ESP,FFFFFFF0 00401B02 |. SUB ESP,10 00401B05 |. CALL GCCOllyT.0040182C 00401B0A |. MOV DWORD PTR SS:[ESP],GCCOllyT.00403024 ; ||ASCII "Hello World!" 00401B11 |. CALL <JMP.&msvcrt.puts> ; |\puts 00401B16 |. MOV DWORD PTR SS:[ESP],GCCOllyT.00403031 ; |ASCII "PAUSE" 00401B1D |. CALL <JMP.&msvcrt.system> ; \system 00401B22 |. XOR EAX,EAX 00401B24 |. LEAVE 00401B25 \. RETN
It is important to note that GCC has optimized the printf call to the puts call. In this case, when you know the line you are looking for, you can use olly in debug mode, right-click and select search for -> all referenced text strings , then just select the desired line from the list to find the code using it , or follow its address to find the .data section entry so you can change it. A longer way to find this is to use the binary search available in the right-click context menu, but this is usually a waste for text strings.
And to cover all the bases, let's assume that we needed to go to the code from the entry point. If we can go to the code from the module entry point, we will follow the chain as follows:
GCCOllyT.<ModuleEntryPoint> 0> $ >PUSH EBP 0040126D . >MOV EBP,ESP 0040126F . >SUB ESP,18 00401272 . >MOV DWORD PTR SS:[ESP],1 00401279 . >CALL DWORD PTR DS:[<&msvcrt.__set_app_type>; msvcrt.__set_app_type 0040127F . >CALL GCCOllyT.00401000 00401284 . >PUSH EBP 00401285 . >MOV EBP,ESP 00401287 . >SUB ESP,18 0040128A . >MOV DWORD PTR SS:[ESP],2 00401291 . >CALL DWORD PTR DS:[<&msvcrt.__set_app_type>; msvcrt.__set_app_type 00401297 . >CALL GCCOllyT.00401000 0040129C $ >PUSH EBP 0040129D . >MOV EBP,ESP 0040129F . >SUB ESP,8 004012A2 . >MOV EAX,DWORD PTR DS:[<&msvcrt.atexit>] 004012A7 . >LEAVE 004012A8 . >JMP EAX
here we see the only viable call as GCCOllyT.00401000 , after which we end here (this is GCC mainCRTstartup ):
00401000 /$ >PUSH EBP 00401001 |. >MOV EBP,ESP 00401003 |. >PUSH EBX 00401004 |. >SUB ESP,34 00401007 |. >MOV EAX,DWORD PTR DS:[403038] 0040100C |. >TEST EAX,EAX 0040100E |. >JE SHORT GCCOllyT.0040102C 00401010 |. >MOV DWORD PTR SS:[ESP+8],0 00401018 |. >MOV DWORD PTR SS:[ESP+4],2 00401020 |. >MOV DWORD PTR SS:[ESP],0 00401027 |. >CALL EAX 00401029 |. >SUB ESP,0C 0040102C |> >MOV DWORD PTR SS:[ESP],GCCOllyT.00401110 ; | 00401033 |. >CALL <JMP.&KERNEL32.SetUnhandledExceptionFilter> ; \SetUnhandledExceptionFilter 00401038 |. >PUSH EAX 00401039 |. >CALL GCCOllyT.004013CC 0040103E |. >CALL GCCOllyT.004014AC 00401043 |. >MOV DWORD PTR SS:[EBP-10],0 0040104A |. >LEA EAX,DWORD PTR SS:[EBP-10] 0040104D |. >MOV DWORD PTR SS:[ESP+10],EAX 00401051 |. >MOV EAX,DWORD PTR DS:[402000] 00401056 |. >MOV DWORD PTR SS:[ESP+C],EAX 0040105A |. >LEA EAX,DWORD PTR SS:[EBP-C] 0040105D |. >MOV DWORD PTR SS:[ESP+8],EAX 00401061 |. >MOV DWORD PTR SS:[ESP+4],GCCOllyT.00404004 00401069 |. >MOV DWORD PTR SS:[ESP],GCCOllyT.00404000 00401070 |. >CALL <JMP.&msvcrt.__getmainargs> 00401075 |. >MOV EAX,DWORD PTR DS:[404018] 0040107A |. >TEST EAX,EAX 0040107C |. >JNZ SHORT GCCOllyT.004010C8 0040107E |> >CALL <JMP.&msvcrt.__p__fmode> 00401083 |. >MOV EDX,DWORD PTR DS:[402004] 00401089 |. >MOV DWORD PTR DS:[EAX],EDX 0040108B |. >CALL GCCOllyT.004015E4 00401090 |. >AND ESP,FFFFFFF0 00401093 |. >CALL GCCOllyT.0040182C 00401098 |. >CALL <JMP.&msvcrt.__p__environ> 0040109D |. >MOV EAX,DWORD PTR DS:[EAX] 0040109F |. >MOV DWORD PTR SS:[ESP+8],EAX 004010A3 |. >MOV EAX,DWORD PTR DS:[404004] 004010A8 |. >MOV DWORD PTR SS:[ESP+4],EAX 004010AC |. >MOV EAX,DWORD PTR DS:[404000] 004010B1 |. >MOV DWORD PTR SS:[ESP],EAX 004010B4 |. >CALL GCCOllyT.00401AFC 004010B9 |. >MOV EBX,EAX ; | 004010BB |. >CALL <JMP.&msvcrt._cexit> ; |[msvcrt._cexit 004010C0 |. >MOV DWORD PTR SS:[ESP],EBX ; | 004010C3 |. >CALL <JMP.&KERNEL32.ExitProcess> ; \ExitProcess 004010C8 |> >MOV DWORD PTR DS:[402004],EAX ; ||| 004010CD |. >MOV DWORD PTR SS:[ESP+4],EAX ; ||| 004010D1 |. >MOV EBX,DWORD PTR DS:[<&msvcrt._iob>] ; |||msvcrt._iob 004010D7 |. >MOV EAX,DWORD PTR DS:[EBX+10] ; ||| 004010DA |. >MOV DWORD PTR SS:[ESP],EAX ; ||| 004010DD |. >CALL <JMP.&msvcrt._setmode> ; ||\_setmode 004010E2 |. >MOV EAX,DWORD PTR DS:[404018] ; || 004010E7 |. >MOV DWORD PTR SS:[ESP+4],EAX ; || 004010EB |. >MOV EAX,DWORD PTR DS:[EBX+30] ; || 004010EE |. >MOV DWORD PTR SS:[ESP],EAX ; || 004010F1 |. >CALL <JMP.&msvcrt._setmode> ; |\_setmode 004010F6 |. >MOV EAX,DWORD PTR DS:[404018] ; | 004010FB |. >MOV DWORD PTR SS:[ESP+4],EAX ; | 004010FF |. >MOV EAX,DWORD PTR DS:[EBX+50] ; | 00401102 |. >MOV DWORD PTR SS:[ESP],EAX ; | 00401105 |. >CALL <JMP.&msvcrt._setmode> ; \_setmode 0040110A \.^>JMP GCCOllyT.0040107E
Now we know that the signature for calling main takes 3 arguments, we also know that it will be called before cleaning and exiting the application, so we get GCCOllyT.00401AFC . As you can see, it pays a lot for the inclusion of characters, this can be done from the disassembly section of the debugging options menu.