NTDebugging Puzzler 0x00000003 (Matrix Edition) Some assembly required.
Hello NTdebuggers, I'm very impressed with the depth of the answers we are seeing from our readers. As I stated in last week's response, this week's puzzler is going to be harder. With that said let's take it up a notch. One of the things that is really cool about be an Escalation Engineer in GES/CPR is how far we go in the pursuit of solving complex problems. If we're debugging some Microsoft code in a kernel dump or user mode, and our quest takes us into a binary that we don't have code or symbols for, we don't stop, we forge on! Over the years there are members of our team that have had to port to or support Alpha, PowerPC, MIPs, IA64 and x64, myself included. As a result most of us have books for just about every mainstream processor under the sun. It's a good idea if you're going to be debugging on these platforms to have general working knowledge the CPUs you will encounter. The most common CPU's we deal with are x86, followed by x64 and IA64. Microsoft doesn't support PPC, MIPS or Alpha anymore unless you're dealing with Xbox consoles, and those are PPC. That said, this week's challenge is to tell us what the following assembly does. You can tell us in C, or break it down and comment on the various sections.
Some people like cross word puzzles, Most of us in GES/CPR love to esreveR reenignE assembler. Have FUN!
“I don’t even see the code anymore” Cypher...
0:000> uf myfun
puzzler3!myfun [c:\source\puzzler\puzzler3\puzzler3\puzzler3.cpp @ 20]:
20 00cc1480 55 push ebp
20 00cc1481 8bec mov ebp,esp
20 00cc1483 81ecf0000000 sub esp,0F0h
20 00cc1489 53 push ebx
20 00cc148a 56 push esi
20 00cc148b 57 push edi
20 00cc148c 8dbd10ffffff lea edi,[ebp-0F0h]
20 00cc1492 b93c000000 mov ecx,3Ch
20 00cc1497 b8cccccccc mov eax,0CCCCCCCCh
20 00cc149c f3ab rep stos dword ptr es:[edi]
26 00cc149e 8b4508 mov eax,dword ptr [ebp+8]
26 00cc14a1 50 push eax
26 00cc14a2 e803fcffff call puzzler3!ILT+165(_strlen) (00cc10aa)
26 00cc14a7 83c404 add esp,4
26 00cc14aa 8945e0 mov dword ptr [ebp-20h],eax
28 00cc14ad 8b45e0 mov eax,dword ptr [ebp-20h]
28 00cc14b0 8945f8 mov dword ptr [ebp-8],eax
28 00cc14b3 eb09 jmp puzzler3!myfun+0x3e (00cc14be)
28 00cc14b5 8b45f8 mov eax,dword ptr [ebp-8]
28 00cc14b8 83e801 sub eax,1
28 00cc14bb 8945f8 mov dword ptr [ebp-8],eax
28 00cc14be 837df800 cmp dword ptr [ebp-8],0
28 00cc14c2 7e60 jle puzzler3!myfun+0xa4 (00cc1524)
30 00cc14c4 c745ec00000000 mov dword ptr [ebp-14h],0
30 00cc14cb eb09 jmp puzzler3!myfun+0x56 (00cc14d6)
30 00cc14cd 8b45ec mov eax,dword ptr [ebp-14h]
30 00cc14d0 83c001 add eax,1
30 00cc14d3 8945ec mov dword ptr [ebp-14h],eax
30 00cc14d6 8b45f8 mov eax,dword ptr [ebp-8]
30 00cc14d9 83e801 sub eax,1
30 00cc14dc 3945ec cmp dword ptr [ebp-14h],eax
30 00cc14df 7d41 jge puzzler3!myfun+0xa2 (00cc1522)
32 00cc14e1 8b4508 mov eax,dword ptr [ebp+8]
32 00cc14e4 0345ec add eax,dword ptr [ebp-14h]
32 00cc14e7 0fbe08 movsx ecx,byte ptr [eax]
32 00cc14ea 8b5508 mov edx,dword ptr [ebp+8]
32 00cc14ed 0355ec add edx,dword ptr [ebp-14h]
32 00cc14f0 0fbe4201 movsx eax,byte ptr [edx+1]
32 00cc14f4 3bc8 cmp ecx,eax
32 00cc14f6 7e28 jle puzzler3!myfun+0xa0 (00cc1520)
34 00cc14f8 8b4508 mov eax,dword ptr [ebp+8]
34 00cc14fb 0345ec add eax,dword ptr [ebp-14h]
34 00cc14fe 8a08 mov cl,byte ptr [eax]
34 00cc1500 884dd7 mov byte ptr [ebp-29h],cl
35 00cc1503 8b4508 mov eax,dword ptr [ebp+8]
35 00cc1506 0345ec add eax,dword ptr [ebp-14h]
35 00cc1509 8b4d08 mov ecx,dword ptr [ebp+8]
35 00cc150c 034dec add ecx,dword ptr [ebp-14h]
35 00cc150f 8a5101 mov dl,byte ptr [ecx+1]
35 00cc1512 8810 mov byte ptr [eax],dl
36 00cc1514 8b4508 mov eax,dword ptr [ebp+8]
36 00cc1517 0345ec add eax,dword ptr [ebp-14h]
36 00cc151a 8a4dd7 mov cl,byte ptr [ebp-29h]
36 00cc151d 884801 mov byte ptr [eax+1],cl
38 00cc1520 ebab jmp puzzler3!myfun+0x4d (00cc14cd)
40 00cc1522 eb91 jmp puzzler3!myfun+0x35 (00cc14b5)
41 00cc1524 5f pop edi
41 00cc1525 5e pop esi
41 00cc1526 5b pop ebx
41 00cc1527 81c4f0000000 add esp,0F0h
41 00cc152d 3bec cmp ebp,esp
41 00cc152f e820fcffff call puzzler3!ILT+335(__RTC_CheckEsp) (00cc1154)
41 00cc1534 8be5 mov esp,ebp
41 00cc1536 5d pop ebp
41 00cc1537 c3 ret
Good luck, and happy debugging.
Jeff Dailey-
In response: Wow, you folks did it again. I was worried that not many of our readers would respond. Our entire team was very impressed with the number and quality of the responses we saw. Congratulations goes out to all those assembler gurus out there that figured out this was a simple bubble sort. We enjoyed seeing how various people went about solving this. Some people compiled their code as they worked on reversing the function to verify the assembler. This is a good approach. Others just seemed to work it out end to end. This is the approach I usually end up using because I’m typically in the middle of a debug and don’t actually need the source.
Great work!
Here is the answer….
void myfun(char *val)
{
00321480 push ebp
00321481 mov ebp,esp
00321483 sub esp,0F0h
00321489 push ebx
0032148A push esi
0032148B push edi
0032148C lea edi,[ebp-0F0h]
00321492 mov ecx,3Ch
00321497 mov eax,0CCCCCCCCh
0032149C rep stos dword ptr es:[edi]
int i;
int j;
int len;
char t;
len=strlen(val);
0032149E mov eax,dword ptr [val]
003214A1 push eax
003214A2 call @ILT+165(_strlen) (3210AAh)
003214A7 add esp,4
003214AA mov dword ptr [len],eax
for (i=len;i>0;i--)
003214AD mov eax,dword ptr [len]
003214B0 mov dword ptr [i],eax
003214B3 jmp myfun+3Eh (3214BEh)
003214B5 mov eax,dword ptr [i]
003214B8 sub eax,1
003214BB mov dword ptr [i],eax
003214BE cmp dword ptr [i],0
003214C2 jle myfun+0A4h (321524h)
{
for(j=0;j<i-1;j++)
003214C4 mov dword ptr [j],0
003214CB jmp myfun+56h (3214D6h)
003214CD mov eax,dword ptr [j]
003214D0 add eax,1
003214D3 mov dword ptr [j],eax
003214D6 mov eax,dword ptr [i]
003214D9 sub eax,1
003214DC cmp dword ptr [j],eax
003214DF jge myfun+0A2h (321522h)
{
if (val[j]>val[j+1])
003214E1 mov eax,dword ptr [val]
003214E4 add eax,dword ptr [j]
003214E7 movsx ecx,byte ptr [eax]
003214EA mov edx,dword ptr [val]
003214ED add edx,dword ptr [j]
003214F0 movsx eax,byte ptr [edx+1]
003214F4 cmp ecx,eax
003214F6 jle myfun+0A0h (321520h)
{
t=val[j];
003214F8 mov eax,dword ptr [val]
003214FB add eax,dword ptr [j]
003214FE mov cl,byte ptr [eax]
00321500 mov byte ptr [t],cl
val[j]=val[j+1];
00321503 mov eax,dword ptr [val]
00321506 add eax,dword ptr [j]
00321509 mov ecx,dword ptr [val]
0032150C add ecx,dword ptr [j]
0032150F mov dl,byte ptr [ecx+1]
00321512 mov byte ptr [eax],dl
val[j+1]=t;
00321514 mov eax,dword ptr [val]
00321517 add eax,dword ptr [j]
0032151A mov cl,byte ptr [t]
0032151D mov byte ptr [eax+1],cl
}
}
00321520 jmp myfun+4Dh (3214CDh)
}
00321522 jmp myfun+35h (3214B5h)
}
00321524 pop edi
00321525 pop esi
00321526 pop ebx
00321527 add esp,0F0h
0032152D cmp ebp,esp
0032152F call @ILT+335(__RTC_CheckEsp) (321154h)
00321534 mov esp,ebp
00321536 pop ebp
00321537 ret
Thank You
Jeff Dailey-
Comments
Anonymous
April 21, 2008
PingBack from http://microsoftnews.askpcdoc.com/?p=3492Anonymous
April 21, 2008
The comment has been removedAnonymous
April 21, 2008
Good puzzler, hadn't used my decompiling skills in a while. I guess now the new puzzler is finding input that makes sense after myfun returns! My solution is on my blog to avoid spoilers.Anonymous
April 21, 2008
void myfun(char *string) { int lenString, countLoop, index; char savedByte; lenString = strlen(string); for (countLoop = lenString; countLoop; countLoop--) { for(index = 0; index < countLoop; index++) { countLoop --; if (string[index] > string[index + 1]) { savedByte = string[index]; string[index] = string[index + 1]; string[index + 1] = savedByte; } } } }Anonymous
April 21, 2008
It's a cdecl function to bubble sort a string of chars into ascending order. I hope you're avoiding spoilers by moderating comments, so code will follow shortly.Anonymous
April 21, 2008
The locals are in a different order, but this seems to match... // Puzzler3.cpp : Defines the entry point for the console application. // #include "Puzzler3.h" #include <string.h> #include <stdio.h> #include <tchar.h> int _tmain(int argc, _TCHAR* argv[]) { // Simple test on myfun char str[] = "Hello there everybody�"; myfun(str); printf(str); return 0; } void myfun(char* str) { // Stir chars in array // to their inherent ranking // like tiny bubbles int len = strlen(str); for(int x = len; x > 0; x--) { for(int y = 0; y < x - 1; y++) { if(str[y] > str[y + 1]) { char c = str[y]; str[y] = str[y + 1]; str[y + 1] = c; } } } }Anonymous
April 21, 2008
Created a C function, hope it isn't too far off. Best Regards, happy reversing! OurFunction(char* OurString) { int StringLength = strlen(OurString); for(;StringLength > 0; StringLength--) { for(int StringLength2 = 0; StringLength - 1 < StringLength2;StringLength++) { if(OurString[StringLength2+1] <= OurString[StringLength2]) .continue; OurString[StringLength2] = OurString[StringLength2+1]; } } } 20 00cc1480 55 push ebp //OurFunction(Char* Param1) 20 00cc1481 8bec mov ebp,esp // 20 00cc1483 81ecf0000000 sub esp,0F0h // 20 00cc1489 53 push ebx // 20 00cc148a 56 push esi // 20 00cc148b 57 push edi // 20 00cc148c 8dbd10ffffff lea edi,[ebp-0F0h] // 20 00cc1492 b93c000000 mov ecx,3Ch // 20 00cc1497 b8cccccccc mov eax,0CCCCCCCCh // 20 00cc149c f3ab rep stos dword ptr es:[edi] //int OurData[60]; 26 00cc149e 8b4508 mov eax,dword ptr [ebp+8] // 26 00cc14a1 50 push eax // 26 00cc14a2 e803fcffff call puzzler3!ILT+165(_strlen) (00cc10aa) // 26 00cc14a7 83c404 add esp,4 // 26 00cc14aa 8945e0 mov dword ptr [ebp-20h],eax // 28 00cc14ad 8b45e0 mov eax,dword ptr [ebp-20h] // 28 00cc14b0 8945f8 mov dword ptr [ebp-8],eax //NeverUsed = StringLength = strlen(param1) 28 00cc14b3 eb09 jmp puzzler3!myfun+0x3e (00cc14be) // 28 00cc14b5 8b45f8 mov eax,dword ptr [ebp-8] //(Loop End) 28 00cc14b8 83e801 sub eax,1 // 28 00cc14bb 8945f8 mov dword ptr [ebp-8],eax // 28 00cc14be 837df800 cmp dword ptr [ebp-8],0 // 28 00cc14c2 7e60 jle puzzler3!myfun+0xa4 (00cc1524) //for(StringLength; StringLength > 0; StringLength--) { // 30 00cc14c4 c745ec00000000 mov dword ptr [ebp-14h],0 // 30 00cc14cb eb09 jmp puzzler3!myfun+0x56 (00cc14d6) // 30 00cc14cd 8b45ec mov eax,dword ptr [ebp-14h] // 30 00cc14d0 83c001 add eax,1 // 30 00cc14d3 8945ec mov dword ptr [ebp-14h],eax // 30 00cc14d6 8b45f8 mov eax,dword ptr [ebp-8] // 30 00cc14d9 83e801 sub eax,1 // 30 00cc14dc 3945ec cmp dword ptr [ebp-14h],eax // 30 00cc14df 7d41 jge puzzler3!myfun+0xa2 (00cc1522) //for(StringLength2 = 0; StringLength-1 < StringLength2 ;StringLength2++) 32 00cc14e1 8b4508 mov eax,dword ptr [ebp+8] // 32 00cc14e4 0345ec add eax,dword ptr [ebp-14h] // 32 00cc14e7 0fbe08 movsx ecx,byte ptr [eax] // 32 00cc14ea 8b5508 mov edx,dword ptr [ebp+8] // 32 00cc14ed 0355ec add edx,dword ptr [ebp-14h] // 32 00cc14f0 0fbe4201 movsx eax,byte ptr [edx+1] // 32 00cc14f4 3bc8 cmp ecx,eax // 32 00cc14f6 7e28 jle puzzler3!myfun+0xa0 (00cc1520) //if(Param1[StringLength2+1] <= Param1[StringLength2]) .continue 34 00cc14f8 8b4508 mov eax,dword ptr [ebp+8] // 34 00cc14fb 0345ec add eax,dword ptr [ebp-14h] // 34 00cc14fe 8a08 mov cl,byte ptr [eax] // 34 00cc1500 884dd7 mov byte ptr [ebp-29h],cl //Previous = Param1[StringLength2] 35 00cc1503 8b4508 mov eax,dword ptr [ebp+8] // 35 00cc1506 0345ec add eax,dword ptr [ebp-14h] // 35 00cc1509 8b4d08 mov ecx,dword ptr [ebp+8] // 35 00cc150c 034dec add ecx,dword ptr [ebp-14h] // 35 00cc150f 8a5101 mov dl,byte ptr [ecx+1] // 35 00cc1512 8810 mov byte ptr [eax],dl //Param1[StringLength] = Param1[StringLength+1] 36 00cc1514 8b4508 mov eax,dword ptr [ebp+8] // 36 00cc1517 0345ec add eax,dword ptr [ebp-14h] // 36 00cc151a 8a4dd7 mov cl,byte ptr [ebp-29h] // 36 00cc151d 884801 mov byte ptr [eax+1],cl //Param1[something+1] = Previous //}}Anonymous
April 21, 2008
Heh, I'm pretty rusty. If I had to guess I'd say its trying to bubble sort the characters in a string something along these lines: void f(char *s) { int len=strlen(str); for(int top=len;top>0;--top) { for(int i=0;i<top-1;++i) { if(str[i]>str[i+1]) { char tmp=str[i]; str[i]=s[i+1]; str[i+1]=tmp; } } } } (I'm not sure about what it returns....)Anonymous
April 21, 2008
No idea how well this will paste but here's my quick analysis (prolly off on the comparisons or some such). <pre> puzzler3!myfun [c:sourcepuzzlerpuzzler3puzzler3puzzler3.cpp @ 20]: ; ; Prologue : 20 00cc1480 55 push ebp 20 00cc1481 8bec mov ebp,esp 20 00cc1483 81ecf0000000 sub esp,0F0h 20 00cc1489 53 push ebx 20 00cc148a 56 push esi 20 00cc148b 57 push edi ; ; 240 bytes of local storage ; 20 00cc148c 8dbd10ffffff lea edi,[ebp-0F0h] ; ; Fill all local space (0xf0) with 0xcc ; ; memset(ebp-0xf0, 0xcc, 0xf0) ; 20 00cc1492 b93c000000 mov ecx,3Ch 20 00cc1497 b8cccccccc mov eax,0CCCCCCCCh 20 00cc149c f3ab rep stos dword ptr es:[edi] ; ; strlen(arg1) ; 26 00cc149e 8b4508 mov eax,dword ptr [ebp + ARG1] 26 00cc14a1 50 push eax 26 00cc14a2 e803fcffff call puzzler3!ILT+165(_strlen) (00cc10aa) 26 00cc14a7 83c404 add esp,4 26 00cc14aa 8945e0 mov dword ptr [ebp - strlen_ARG1],eax ; ; For (i = strlen(ARG1) ; i > 0; i--) ; ; ; i = strlen(ARG1) ; 28 00cc14ad 8b45e0 mov eax,dword ptr [ebp - strlen_ARG1] 28 00cc14b0 8945f8 mov dword ptr [ebp - i],eax 28 00cc14b3 eb09 jmp puzzler3!myfun+0x3e (00cc14be) ; ; OUTER_LOOP_CONTINUE ; ; ; i-- ; 28 00cc14b5 8b45f8 mov eax,dword ptr [ebp - i] 28 00cc14b8 83e801 sub eax,1 28 00cc14bb 8945f8 mov dword ptr [ebp - i],eax ; ; Check i > 0 ; 28 00cc14be 837df800 cmp dword ptr [ebp - i],0 28 00cc14c2 7e60 jle puzzler3!myfun+0xa4 (00cc1524) ; END_OUTER_LOOP ; ; //for ; ; ; for (j = 0 ; j < i - 1; j++) ; ; ; j = 0 ; 30 00cc14c4 c745ec00000000 mov dword ptr [ebp - j],0 30 00cc14cb eb09 jmp puzzler3!myfun+0x56 (00cc14d6) ; ; INNER_LOOP_CONTINUE ; ; ; j = j + 1 ; 30 00cc14cd 8b45ec mov eax,dword ptr [ebp - j] 30 00cc14d0 83c001 add eax,1 30 00cc14d3 8945ec mov dword ptr [ebp - j],eax ; ; Check j < i - 1 ; 30 00cc14d6 8b45f8 mov eax,dword ptr [ebp - i] 30 00cc14d9 83e801 sub eax,1 30 00cc14dc 3945ec cmp dword ptr [ebp - j],eax 30 00cc14df 7d41 jge puzzler3!myfun+0xa2 (00cc1522) ; INNER_LOOP_DONE ; ; char c = ARG1[j] ; 32 00cc14e1 8b4508 mov eax,dword ptr [ebp + ARG1] 32 00cc14e4 0345ec add eax,dword ptr [ebp - j] 32 00cc14e7 0fbe08 movsx ecx,byte ptr [eax] ; ; char d = ARG1[j+1] ; 32 00cc14ea 8b5508 mov edx,dword ptr [ebp + ARG1] 32 00cc14ed 0355ec add edx,dword ptr [ebp - j] 32 00cc14f0 0fbe4201 movsx eax,byte ptr [edx+1] ; ; if (c > d) { // signed compare ; 32 00cc14f4 3bc8 cmp ecx,eax 32 00cc14f6 7e28 jle puzzler3!myfun+0xa0 (00cc1520) ; ; unsigned char e = ARG1[j] ; 34 00cc14f8 8b4508 mov eax,dword ptr [ebp + ARG1] 34 00cc14fb 0345ec add eax,dword ptr [ebp - j] 34 00cc14fe 8a08 mov cl,byte ptr [eax] 34 00cc1500 884dd7 mov byte ptr [ebp-29h],cl ; ; ARG[j] = ARG[j+1] ; 35 00cc1503 8b4508 mov eax,dword ptr [ebp + ARG1] 35 00cc1506 0345ec add eax,dword ptr [ebp - j] 35 00cc1509 8b4d08 mov ecx,dword ptr [ebp + ARG1] 35 00cc150c 034dec add ecx,dword ptr [ebp - j] 35 00cc150f 8a5101 mov dl,byte ptr [ecx+1] 35 00cc1512 8810 mov byte ptr [eax],dl ; ; ARG[j+1] = e ; 36 00cc1514 8b4508 mov eax,dword ptr [ebp + ARG1] 36 00cc1517 0345ec add eax,dword ptr [ebp - j] 36 00cc151a 8a4dd7 mov cl,byte ptr [ebp-29h] 36 00cc151d 884801 mov byte ptr [eax+1],cl ; ; } // if ; 38 00cc1520 ebab jmp puzzler3!myfun+0x4d (00cc14cd) ; INNER_LOOP_CONTINUE ; ; INNER_LOOP_DONE ; 40 00cc1522 eb91 jmp puzzler3!myfun+0x35 (00cc14b5) ; OUTER_LOOP_CONTINUE ; ; END_OUTER_LOOP ; 41 00cc1524 5f pop edi 41 00cc1525 5e pop esi 41 00cc1526 5b pop ebx 41 00cc1527 81c4f0000000 add esp,0F0h 41 00cc152d 3bec cmp ebp,esp 41 00cc152f e820fcffff call puzzler3!ILT+335(__RTC_CheckEsp) (00cc1154) 41 00cc1534 8be5 mov esp,ebp 41 00cc1536 5d pop ebp 41 00cc1537 c3 ret void myfun(char *mystr) { int i, j; int len; len = strlen(mystr); for (i = len; i > 0; i--) { for (j = 0; j < i - 1; j++) { if (mystr[j] < mystr[j+1]) { unsigned char c = mystr[j]; mystr[j] = mystr[j+1]; mystr[j+1] = c; } } } } </pre>Anonymous
April 21, 2008
bubble sort! There are too many give aways from debug build disassembly. Can't wait next monday night again :)Anonymous
April 21, 2008
bubble sort! There are too many give away from debug build disassembly :)Anonymous
April 21, 2008
A debug-compiled version of: void bubble_sort(char* array) { int unused, curr_len; curr_len = unused =(int)strlen(array); for ( ; curr_len > 0; curr_len--) { for (int i = 0; i < (curr_len - 1); i++) { if ( *(array + i) > *(array + i +1) ) { char tmp = *(array + i); *(array + i) = *(array + i +1); *(array + i +1) = tmp; } } } }Anonymous
April 21, 2008
void myfun(char *pszText) { int i, j; char t; i = strlen(pszText); for( ; i > 0; --i) { for(j = 0; j < i - 1; ++j) { if(pszText[j] > pszText[j + 1]) { t = pszText[j]; pszText[j] = pszText[j + 1]; pszText[j + 1] = t; } } } return pszText; }Anonymous
April 21, 2008
void myfun(char *pszText) { int i, j; char t; i = strlen(pszText); for( ; i > 0; --i) { for(j = 0; j < i - 1; ++j) { if(pszText[j] > pszText[j + 1]) { t = pszText[j]; pszText[j] = pszText[j + 1]; pszText[j + 1] = t; } } } }Anonymous
April 21, 2008
This was fun! :) Looks like a bubble-sort for strings?Anonymous
April 21, 2008
Here's my rough first-cut take on it, though I'm a bit rusty with asm! It is a function that takes in a string and rearranges the letters in it so that they are in alphabetical order (e.g. "aziewe" becomes "aeeiwz"). void myfun(char* s) { int len = (int)strlen(s); for (int i = len; i > 0; i--) { for (int j = 0; j < i-1; j++) { char* p = s+j; char ch1 = *p; char ch2 = *(p+1); if (ch1 > ch2) { *p = ch2; *(p+1) = ch1; } } } } -AledAnonymous
April 22, 2008
it sorts the chars in the given string in ascii order. void myfun (char *str) { int i, j, len; char c; len = strlen (str); for (i = len; i > 0; --i) { for (j = 0; j < i - 1; ++j) { if (str[j] > str[j + 1]) { c = str[j]; str[j] = str[j + 1]; str[j + 1] = c; } } } }Anonymous
April 22, 2008
It's a simple bubble sort :) http://rafb.net/p/GYi6OL16.htmlAnonymous
April 22, 2008
It's a simple bubble sort :) http://rafb.net/p/GYi6OL16.htmlAnonymous
April 22, 2008
I didn't have a lot of time to make sure, but it appears (backwards to avoid spoilers): redro lacitebahpla ni tros ot Hopefully I'll have time to finish marking up the code (and make sure I was right)Anonymous
April 22, 2008
OK - be gentle... My first "substantial" attempt at reversing... I've spent way too much time on this... ;-/ (Hope the code formatting doesn't get messed up...) void myfun( char* param1 ) { char local4 = 0; size_t local1 = strlen( param1 ); for( int local2 = local1; local2 > 0; local2-- ) { for( int local3 = 0; local3 < local2 - 1; local3++ ) { if( *(param1+local3) > *(param1+local3+1) ) { char local4 = *(param1+local3); *(param1+local3) = *(param1+local3+1); *(param1+local3+1) = local4; } } } }Anonymous
April 22, 2008
Ack... Forgot to yank a leftover local I had used for experimenting... Sorry for the noise. Here it is again, with the local removed. void myfun( char* param1 ) { size_t local1 = strlen( param1 ); for( int local2 = local1; local2 > 0; local2-- ) { for( int local3 = 0; local3 < local2 - 1; local3++ ) { if( *(param1+local3) > *(param1+local3+1) ) { char local4 = *(param1+local3); *(param1+local3) = *(param1+local3+1); *(param1+local3+1) = local4; } } } }Anonymous
April 22, 2008
void myfun(char *string) { int lenString, countLoop, index; char savedByte; lenString = strlen(string); for (countLoop = lenString; countLoop; countLoop--) { for(index = 0; index < (countLoop - 1); index++) { if (string[index] > string[index + 1]) { savedByte = string[index]; string[index] = string[index + 1]; string[index + 1] = savedByte; } } } }Anonymous
April 22, 2008
for (i = strlen(arg_0); i > 0; i--) for (j = 0; j < (i - 1); j++) if (arg_0[j] > arg_0[j + 1]) { b = arg_0[j]; arg_0[j] = arg_0[j + 1]; arg_0[j + 1] = b; }Anonymous
April 22, 2008
The comment has been removedAnonymous
April 22, 2008
hello, nice blog. I'm thinking it's a bubble sorting function (or something similar) ... // it was compiled with /RTC :) void bubble_sort( char * cpString ) { int lenght; int index; char c; length = strlen( cpString ); for( ; length > 0 ; length-- ) { for( index = 0 ; index < length ; index++ ) { if( cpString[index] > cpString[index+1] ) { char c = cpString[index]; cpString[index] = cpString[index+1]; cpString[index+1] = c; } } } }Anonymous
April 22, 2008
Hello! Thanks for this puzzle, it was so fun. Okay, let me guess.. This assembly code looks like actually "reversing" the string which was given as third parameter(ebp+8). void myfun(char* szStr, int dummy, int dummy2) { dummy = 0; dummy2 = 0; int strLength; int LocalVar1; char temp; strLength = (int)strlen(szStr); for (;strLength > 0;strLength--) { LocalVar1 = 0; do { if (LocalVar1 >= strLength -1) { break; } if (*(szStr + LocalVar1) <= *(szStr + LocalVar1 + 1)) { continue; } temp = *(szStr + LocalVar1); *(szStr + LocalVar1) = *(szStr + LocalVar1 + 1); *(szStr + LocalVar1+1) = temp; } while (LocalVar1 ++); } } Heejune.Anonymous
April 22, 2008
Oops! Sorry I posted wrong, old source code. following is a revised version, sorry for inconvenient.
void myfun(char* szStr, int dummy, int dummy2) { dummy = 0; dummy2 = 0; int strLength; int LocalVar1; char temp; strLength = (int)strlen(szStr); for (;strLength > 0;strLength--) { LocalVar1 = 0; for (;;LocalVar1 ++) { if (LocalVar1 >= strLength -1) { break; } if (*(szStr + LocalVar1) <= *(szStr + LocalVar1 + 1)) { continue; } temp = *(szStr + LocalVar1); *(szStr + LocalVar1) = *(szStr + LocalVar1 + 1); *(szStr + LocalVar1+1) = temp; } } } Heejune.
Anonymous
April 23, 2008
Nice blog. Its very interesting. And nice... ¿string reversing code? (I dont have free time enough for a in deep analisys) Im sorry, my english is very poor :o)Anonymous
April 24, 2008
void charsort(char *buf) { int len=strlen(buf); for(int k=len;k>0;--k) { for(int j=0;j<k-1;++j) { if(buf[j]>buf[j+1]) { char c=buf[j]; buf[j]=buf[j+1]; buf[j+1]=c; } } } }Anonymous
April 24, 2008
How do you want to get the result of this? I have a C code which "almost" compiles to the same code. The stack locations for the automatic variables are not exactly the same, and sometimes, my compiler (MSVC6) uses different registers for the same thing. Should I post the code here?Anonymous
April 24, 2008
Oh, it seems this blog is moderated? So, I believe it is correct to send the code directly: Here it is (and I hope the formatting will survive the posting here): #include <string.h> void myfun(char * p, int n) { /* the stack layout is not exactly like the original / int i, j, k; char c; char buffer[160]; /!< ununsed buffer / i = strlen(p); for ( j = i; j > 0; j-- ) { for ( k = 0; k < j; k++ ) { / * Huh? Swap p[k] and p[k+1] if they are identical? * This does not make much sense, does it? */ if ( p[k] == p[k+1] ) { c = p[k]; p[k] = p[k+1]; p[k+1] = c; } } } } Now, what sense does this code have? IMHO, there is no sense at all. It goes through the input buffer pointed to by p and exchanges consecutive characters if they are equal. Additionally, it proceeds multiple times through the buffer. There is no sense at all.Anonymous
April 24, 2008
"Like a splinter in your mind" Morpheus It was a valuable exercise. I started by using an array instead of 4 local variables, and that added an extra call to _RTC_CheckStackVars. void myfun2(char *x) { int a, b, c; char d; c = strlen(x); a = c; for(;a > 0; a --) { b = 0; for(;b < a - 1; b ++) { if(x[b] > x[b + 1]) { d = x[b]; x[b] = x[b + 1]; x[b + 1] = d; } } } }Anonymous
April 24, 2008
myfun( pstr pStrParam ) { // alphabetize pStrParam int nStrParamLength = strlen( pStrParam ); for( int nStrParamCurrent = nStrParamLength; nStrParamCurrent > 0; nStrParamCurrent-- ) for( int nStrParamIndex = 0; nStrParamCurrent - 1 < nStrParamIndex; ++nStrParamIndex ) { if( pStrParam[ nStrParamIndex ] > pStrParam[ nStrParamIndex + 1 ] { char cCurrent = pStrParam[ nStrParamIndex ]; pStrParam[ nStrParamIndex ] = pStrParam[ nStrParamIndex + 1 ]; pStrParam[ nStrParamIndex + 1 ] = cCurrent; } } } }Anonymous
April 24, 2008
Here's the C code I reverse this into: #include <stdio.h> #include <tchar.h> #include <windows.h> void myfun(char ); int _tmain(int argc, _TCHAR argv[]) { char * pszData[80]; strcpy(pszData, "I don't even see the code anymore"); printf("Before: %sn", pszData); myfun(pszData); printf("After : %sn", pszData); getchar(); return 0; } void myfun(char * psz) { char ch; int i; int z1, z2; z1 = strlen(psz); for (z2=z1; z2 > 0; z2--) { for (i=0; i < z2-1; i++) { if (psz[i] > psz[i+1]) { ch = psz[i]; psz[i] = psz[i+1]; psz[i+1] = ch; } } } } Which results in this: Before: I don't even see the code anymore After : 'Iacddeeeeeeehmnnnooorsttvy Basically, it in-place sorts the characters. Here another test: Before: AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz After : ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz Now I wonder how Phoenix would have done...Anonymous
April 25, 2008
The comment has been removedAnonymous
April 25, 2008
Oh... I read the JLE wrong. Yes, it makes more sense if the variables are not identical. ;) And there were some other "minor" errors. I must admit I undid the compilation in the train with paper and pencil. I might have spotted this error if I did it on the computer. And: I must tell that the debug build reveals much of the original structure. Anyway, I am still puzzled why the compiler generated this stack frame in this way. Is it because it is C++ and I missed something important? Is it any "anti-malware" aspect of the newer compilers?