This Markdown file provides an in-depth breakdown of three assembly functions extracted from an ELF file, representing a C program that takes user input, checks it against a computed value (derived from initial constants), and outputs a success or failure message. The messages are encoded using a ROT-3 cipher (subtract 3 from each character byte), and the shift function decodes and prints them. The analysis includes detailed line-by-line explanations, assembly code snippets, extrapolated C-like pseudocode, and logic flow represented in Mermaid diagrams.
- Program Logic: The
mainfunction prompts the user, reads an integer input, computes a target value (90 + 492 = 582, then 582 squared = 338724), and callstestwith the input and target. Thetestfunction compares them and callsshifton the appropriate encoded string address. Theshiftfunction decodes the string in place by subtracting 3 from each byte and then prints it usingprintf. - Key Addresses:
- Prompt strings: Likely at 0x8048610 and 0x8048629 (e.g., "Enter password:" and similar).
- Scanf format: At 0x8048634 (likely "%d").
- Failure string (encoded): At 0x80485ec ("Lqydolg#Sdvvzrug$").
- Success string (encoded): At 0x80485fe ("Sdvvzrug#RN$$$#='").
- Assumptions: Based on x86 assembly (32-bit), strings are in .data section (writable). User input is an integer compared directly.
-
Address:
08048498 -
Purpose: Sets up the environment, displays prompts, reads user input as an integer, computes the target value, calls
testfor validation, and exits. -
Detailed Breakdown (Line-by-Line):
8048498: 55 push ebp: Pushes the base pointer to save the caller's stack frame.8048499: 89 e5 mov ebp,esp: Sets the base pointer to the current stack pointer, establishing the local stack frame.804849b: 83 ec 18 sub esp,0x18: Allocates 24 bytes on the stack for local variables.804849e: 83 e4 f0 and esp,0xfffffff0: Aligns the stack pointer to a 16-byte boundary for optimization/SSE.80484a1: b8 00 00 00 00 mov eax,0x0: Loads 0 into EAX (start of dynamic stack allocation calculation).80484a6: 83 c0 0f add eax,0xf: Adds 15 to EAX.80484a9: 83 c0 0f add eax,0xf: Adds another 15 (total 30, for rounding up).80484ac: c1 e8 04 shr eax,0x4: Shifts right by 4 (divides by 16).80484af: c1 e0 04 shl eax,0x4: Shifts left by 4 (multiplies by 16, rounding to nearest 16-byte multiple).80484b2: 29 c4 sub esp,eax: Subtracts the calculated value from ESP to allocate aligned space.80484b4: c7 04 24 10 86 04 08 mov DWORD PTR [esp],0x8048610: Loads the first prompt string address onto the stack.80484bb: e8 90 fe ff ff call 8048350 <printf@plt>: Callsprintfto display the first prompt.80484c0: c7 04 24 29 86 04 08 mov DWORD PTR [esp],0x8048629: Loads the second prompt string address.80484c7: e8 84 fe ff ff call 8048350 <printf@plt>: Callsprintffor the second prompt.80484cc: 8d 45 fc lea eax,[ebp-0x4]: Loads the address of a local variable (input buffer) into EAX.80484cf: 89 44 24 04 mov DWORD PTR [esp+0x4],eax: Pushes the input buffer address as the second argument.80484d3: c7 04 24 34 86 04 08 mov DWORD PTR [esp],0x8048634: Pushes the format string address ("%d").80484da: e8 51 fe ff ff call 8048330 <scanf@plt>: Callsscanfto read the integer input.80484df: c7 45 f8 5a 00 00 00 mov DWORD PTR [ebp-0x8],0x5a: Sets a local variable to 90 (0x5a).80484e6: c7 45 f4 ec 01 00 00 mov DWORD PTR [ebp-0xc],0x1ec: Sets another to 492 (0x1ec).80484ed: 8b 55 f4 mov edx,DWORD PTR [ebp-0xc]: Loads 492 into EDX.80484f0: 8d 45 f8 lea eax,[ebp-0x8]: Loads address of the first variable.80484f3: 01 10 add DWORD PTR [eax],edx: Adds 492 to 90 (result: 582 / 0x246).80484f5: 8b 45 f8 mov eax,DWORD PTR [ebp-0x8]: Loads 582 into EAX.80484f8: 0f af 45 f8 imul eax,DWORD PTR [ebp-0x8]: Multiplies EAX by itself (582 * 582 = 338724 / 0x52d04).80484fc: 89 45 f4 mov DWORD PTR [ebp-0xc],eax: Stores the squared result.80484ff: 8b 45 f4 mov eax,DWORD PTR [ebp-0xc]: Loads the target into EAX.8048502: 89 44 24 04 mov DWORD PTR [esp+0x4],eax: Pushes target as second argument.8048506: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]: Loads user input.8048509: 89 04 24 mov DWORD PTR [esp],eax: Pushes input as first argument.804850c: e8 5d ff ff ff call 804846e <test>: Calls thetestfunction.8048511: b8 00 00 00 00 mov eax,0x0: Sets return value to 0.8048516: c9 leave: Restores stack frame.8048517: c3 ret: Returns from main.- Padding nops (8048518 to 804851f): No-op instructions for alignment.
-
Assembly Code Snippet:
08048498 <main>: 8048498: 55 push ebp 8048499: 89 e5 mov ebp,esp 804849b: 83 ec 18 sub esp,0x18 804849e: 83 e4 f0 and esp,0xfffffff0 80484a1: b8 00 00 00 00 mov eax,0x0 80484a6: 83 c0 0f add eax,0xf 80484a9: 83 c0 0f add eax,0xf 80484ac: c1 e8 04 shr eax,0x4 80484af: c1 e0 04 shl eax,0x4 80484b2: 29 c4 sub esp,eax 80484b4: c7 04 24 10 86 04 08 mov DWORD PTR [esp],0x8048610 80484bb: e8 90 fe ff ff call 8048350 <printf@plt> 80484c0: c7 04 24 29 86 04 08 mov DWORD PTR [esp],0x8048629 80484c7: e8 84 fe ff ff call 8048350 <printf@plt> 80484cc: 8d 45 fc lea eax,[ebp-0x4] 80484cf: 89 44 24 04 mov DWORD PTR [esp+0x4],eax 80484d3: c7 04 24 34 86 04 08 mov DWORD PTR [esp],0x8048634 80484da: e8 51 fe ff ff call 8048330 <scanf@plt> 80484df: c7 45 f8 5a 00 00 00 mov DWORD PTR [ebp-0x8],0x5a 80484e6: c7 45 f4 ec 01 00 00 mov DWORD PTR [ebp-0xc],0x1ec 80484ed: 8b 55 f4 mov edx,DWORD PTR [ebp-0xc] 80484f0: 8d 45 f8 lea eax,[ebp-0x8] 80484f3: 01 10 add DWORD PTR [eax],edx 80484f5: 8b 45 f8 mov eax,DWORD PTR [ebp-0x8] 80484f8: 0f af 45 f8 imul eax,DWORD PTR [ebp-0x8] 80484fc: 89 45 f4 mov DWORD PTR [ebp-0xc],eax 80484ff: 8b 45 f4 mov eax,DWORD PTR [ebp-0xc] 8048502: 89 44 24 04 mov DWORD PTR [esp+0x4],eax 8048506: 8b 45 fc mov eax,DWORD PTR [ebp-0x4] 8048509: 89 04 24 mov DWORD PTR [esp],eax 804850c: e8 5d ff ff ff call 804846e <test> 8048511: b8 00 00 00 00 mov eax,0x0 8048516: c9 leave 8048517: c3 ret -
C-like Pseudocode:
int main() { int input; int var1 = 90; // 0x5a int var2 = 492; // 0x1ec printf("Prompt string 1\n"); // Address 0x8048610 printf("Prompt string 2\n"); // Address 0x8048629 scanf("%d", &input); // Address 0x8048634 for format var1 += var2; // 582 var2 = var1 * var1; // 338724 test(input, var2); return 0; }
-
Mermaid Diagram (Logic Flow):
Loadinggraph TD A[Start Main] --> B[Setup Stack Frame & Align] B --> C[Allocate Dynamic Stack Space] C --> D[Print Prompt 1] D --> E[Print Prompt 2] E --> F[Read User Input via scanf] F --> G[Initialize var1=90, var2=492] G --> H[Add: var1 += var2 // 582] H --> I[Square: var2 = var1 * var1 // 338724] I --> J[Call test: input, var2] J --> K[Return 0] K --> L[End Main]
-
Address:
0804846e -
Purpose: Compares the user input with the target value. If equal, calls
shifton the success string (decodes and prints it); otherwise, on the failure string. -
Detailed Breakdown (Line-by-Line):
804846e: 55 push ebp: Saves the caller's base pointer.804846f: 89 e5 mov ebp,esp: Establishes the local stack frame.8048471: 83 ec 08 sub esp,0x8: Allocates 8 bytes on the stack (unused, possibly for alignment).8048474: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]: Loads user input (first argument) into EAX.8048477: 3b 45 0c cmp eax,DWORD PTR [ebp+0xc]: Compares input with target (second argument).804847a: 74 0e je 804848a: If equal, jumps to success branch.804847c: c7 04 24 ec 85 04 08 mov DWORD PTR [esp],0x80485ec: (Failure branch) Loads failure string address ("Lqydolg#Sdvvzrug$") onto stack.8048483: e8 8c ff ff ff call 8048414 <shift>: Callsshiftto decode and print failure string.8048488: eb 0c jmp 8048496: Jumps to end.804848a: c7 04 24 fe 85 04 08 mov DWORD PTR [esp],0x80485fe: (Success branch) Loads success string address ("Sdvvzrug#RN$$$#=,").8048491: e8 7e ff ff ff call 8048414 <shift>: Callsshiftto decode and print success string.8048496: c9 leave: Restores stack frame.8048497: c3 ret: Returns from test.
-
Assembly Code Snippet:
0804846e <test>: 804846e: 55 push ebp 804846f: 89 e5 mov ebp,esp 8048471: 83 ec 08 sub esp,0x8 8048474: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] 8048477: 3b 45 0c cmp eax,DWORD PTR [ebp+0xc] 804847a: 74 0e je 804848a <test+0x1c> 804847c: c7 04 24 ec 85 04 08 mov DWORD PTR [esp],0x80485ec 8048483: e8 8c ff ff ff call 8048414 <shift> 8048488: eb 0c jmp 8048496 <test+0x28> 804848a: c7 04 24 fe 85 04 08 mov DWORD PTR [esp],0x80485fe 8048491: e8 7e ff ff ff call 8048414 <shift> 8048496: c9 leave 8048497: c3 ret -
C-like Pseudocode:
void test(int input, int target) { if (input == target) { shift(0x80485fe); // Decode and print "Sdvvzrug#RN$$$#=," -> "Password OK :);" } else { shift(0x80485ec); // Decode and print "Lqydolg#Sdvvzrug$" -> "Invalid Password!" } }
-
Mermaid Diagram (Logic Flow):
Loadinggraph TD A[Start Test] --> B[Setup Stack Frame] B --> C[Load Input into EAX] C --> D[Compare Input == Target] D -->|Equal| E[Load Success String Address: 0x80485fe] E --> F[Call shift on Sdvvzrug#RN$$$#='] F --> I[End Test] D -->|Not Equal| G[Load Failure String Address: 0x80485ec] G --> H[Call shift on Lqydolg#Sdvvzrug$] H --> I[End Test]
-
Address:
08048414 -
Purpose: Takes a string pointer, decodes it in place by subtracting 3 from each character (ROT-3 decode), then prints the decoded string using
printf. -
Detailed Breakdown (Line-by-Line):
8048414: 55 push ebp: Saves base pointer.8048415: 89 e5 mov ebp,esp: Establishes frame.8048417: 81 ec 98 00 00 00 sub esp,0x98: Allocates 152 bytes (large for safety, possibly buffer).804841d: c7 45 84 00 00 00 00 mov DWORD PTR [ebp-0x7c],0x0: Initializes loop index i = 0.8048424: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]: Loads string pointer into EAX.8048427: 89 04 24 mov DWORD PTR [esp],eax: Pushes string for strlen.804842a: e8 11 ff ff ff call 8048340 <strlen@plt>: Calls strlen, result in EAX.804842f: 89 45 88 mov DWORD PTR [ebp-0x78],eax: Stores length in [ebp-0x78].8048432: 8b 45 84 mov eax,DWORD PTR [ebp-0x7c]: Loads i into EAX.8048435: 3b 45 88 cmp eax,DWORD PTR [ebp-0x78]: Compares i < len.8048438: 73 18 jae 8048452: If i >= len, jumps to end of loop (note: image shows 73 for jae).804843a: 8b 55 84 mov edx,DWORD PTR [ebp-0x7c]: Loads i into EDX.804843d: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]: Loads string base.8048440: 01 d0 add eax,edx: Computes str + i.8048442: 0f b6 00 movzx eax,BYTE PTR [eax]: Loads byte at str[i] (zero-extended).8048445: 2c 03 sub al,0x3: Subtracts 3 (decode).8048447: 88 00 mov BYTE PTR [eax],al: Stores back the decoded byte (note: likely should bemov BYTE PTR [edx+eax], aldue to addressing error).8048449: 83 45 84 01 add DWORD PTR [ebp-0x7c],0x1: Increments i.804844d: eb d5 jmp 8048424: Jumps back to loop start.804844f: 90 nop: Alignment nop.8048450: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]: Loads decoded string pointer.8048453: 89 04 24 mov DWORD PTR [esp],eax: Pushes for printf.8048456: e8 f5 fe ff ff call 8048350 <printf@plt>: Calls printf to output the string.804845b: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]: Loads string pointer (return value).804845e: c9 leave: Restores frame.804845f: c3 ret: Returns the string pointer.
-
Assembly Code Snippet:
08048414 <shift>: 8048414: 55 push ebp 8048415: 89 e5 mov ebp,esp 8048417: 81 ec 98 00 00 00 sub esp,0x98 804841d: c7 45 84 00 00 00 00 mov DWORD PTR [ebp-0x7c],0x0 8048424: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] 8048427: 89 04 24 mov DWORD PTR [esp],eax 804842a: e8 11 ff ff ff call 8048340 <strlen@plt> 804842f: 89 45 88 mov DWORD PTR [ebp-0x78],eax 8048432: 8b 45 84 mov eax,DWORD PTR [ebp-0x7c] 8048435: 3b 45 88 cmp eax,DWORD PTR [ebp-0x78] 8048438: 73 18 jae 8048452 <shift+0x3e> 804843a: 8b 55 84 mov edx,DWORD PTR [ebp-0x7c] 804843d: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] 8048440: 01 d0 add eax,edx 8048442: 0f b6 00 movzx eax,BYTE PTR [eax] 8048445: 2c 03 sub al,0x3 8048447: 88 00 mov BYTE PTR [eax],al 8048449: 83 45 84 01 add DWORD PTR [ebp-0x7c],0x1 804844d: eb d5 jmp 8048424 <shift+0x10> 804844f: 90 nop 8048450: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] 8048453: 89 04 24 mov DWORD PTR [esp],eax 8048456: e8 f5 fe ff ff call 8048350 <printf@plt> 804845b: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] 804845e: c9 leave 804845f: c3 ret -
C-like Pseudocode:
char* shift(char* str) { int len = strlen(str); for (int i = 0; i < len; i++) { str[i] -= 3; // ROT-3 decode (e.g., "Lqydolg#Sdvvzrug$" -> "Invalid#Password$") } // or "Sdvvzrug#RN$$$#=" -> "Password#OK$$$#;" printf("%s\n", str); return str; }
-
Mermaid Diagram (Logic Flow):
Loadinggraph TD A[Start Shift] --> B[Setup Stack Frame] B --> C[Initialize i = 0] C --> D[Compute len = strlen: str] D --> E[Compare i < len] E -->|Yes| F[Load str at i] F --> G[Subtract 3 from str at i] G --> H[Store back to str at i] H --> I[Increment i] I --> D[Loop Back] E -->|No| J[Load Decoded str] J --> K[Call printf on str] K --> L[Return str Pointer] L --> M[End Shift]
- Security Implications: Modifying strings in place assumes a writable data section; in modern systems, this might trigger protections (e.g., W^X).
- Decoding Example:
- "Lqydolg#Sdvvzrug$" (0x80485ec) decodes to "Invalid#Password$" (L-3=I, q-3=n, etc.).
- "Sdvvzrug#RN$$$#=" (0x80485fe) decodes to "Password#OK$$$#;" (S-3=P, d-3=a, etc.).
- Target Value: User must input 338724 for success.
- Potential Improvements: In C, use
const char*for strings, but here modification is intentional for obfuscation.