Задачи
From Wiki.conus.info
Почти для всех задач, если не указано иное, два вопроса:
- Что делает эта функция? Ответ должен состоять из одной фразы.
- Перепишите эту функцию на Си.
Чтобы подсмотреть подсказки или ответы, выделите мышью. Чтобы подсмотреть исходник из которого получился приведенный код, нажмите на этой странице "edit" или "view source" - исходники скрыты в HTML-комментариях.
Contents |
Легкий уровень
1
Это стандартная функция из библиотек Си. Исходник взят из OpenWatcom. Скомпилировано в MSVC 2010.
_TEXT SEGMENT _input$ = 8 ; size = 1 _f PROC push ebp mov ebp, esp movsx eax, BYTE PTR _input$[ebp] cmp eax, 97 ; 00000061H jl SHORT $LN1@f movsx ecx, BYTE PTR _input$[ebp] cmp ecx, 122 ; 0000007aH jg SHORT $LN1@f movsx edx, BYTE PTR _input$[ebp] sub edx, 32 ; 00000020H mov BYTE PTR _input$[ebp], dl $LN1@f: mov al, BYTE PTR _input$[ebp] pop ebp ret 0 _f ENDP _TEXT ENDS
Это он же скомпилирован GCC 4.4.1 с опцией -O3 (максимальная оптимизация):
_f proc near input = dword ptr 8 push ebp mov ebp, esp movzx eax, byte ptr [ebp+input] lea edx, [eax-61h] cmp dl, 19h ja short loc_80483F2 sub eax, 20h loc_80483F2: pop ebp retn _f endp
Ответ: toupper()
Исходник на Си:
2
Это также стандартная функция из библиотек Си. Исходник взят из OpenWatcom и немного переделан. Скомпилировано в MSVC 2010 с флагом (/Ox).
Эта функция использует isspace() и isdigit().
EXTRN _isdigit:PROC EXTRN _isspace:PROC EXTRN ___ptr_check:PROC ; Function compile flags: /Ogtpy _TEXT SEGMENT _p$ = 8 ; size = 4 _f PROC push ebx push esi mov esi, DWORD PTR _p$[esp+4] push edi push 0 push esi call ___ptr_check mov eax, DWORD PTR [esi] push eax call _isspace add esp, 12 ; 0000000cH test eax, eax je SHORT $LN6@f npad 2 $LL7@f: mov ecx, DWORD PTR [esi+4] add esi, 4 push ecx call _isspace add esp, 4 test eax, eax jne SHORT $LL7@f $LN6@f: mov bl, BYTE PTR [esi] cmp bl, 43 ; 0000002bH je SHORT $LN4@f cmp bl, 45 ; 0000002dH jne SHORT $LN5@f $LN4@f: add esi, 4 $LN5@f: mov edx, DWORD PTR [esi] push edx xor edi, edi call _isdigit add esp, 4 test eax, eax je SHORT $LN2@f $LL3@f: mov ecx, DWORD PTR [esi] mov edx, DWORD PTR [esi+4] add esi, 4 lea eax, DWORD PTR [edi+edi*4] push edx lea edi, DWORD PTR [ecx+eax*2-48] call _isdigit add esp, 4 test eax, eax jne SHORT $LL3@f $LN2@f: cmp bl, 45 ; 0000002dH jne SHORT $LN14@f neg edi $LN14@f: mov eax, edi pop edi pop esi pop ebx ret 0 _f ENDP _TEXT ENDS
То же скомпилировано в GCC 4.4.1. Задача немного усложняется тем, что GCC представил isspace() и isdigit() как inline-функции и вставил их тела прямо в код.
_f proc near var_10 = dword ptr -10h var_9 = byte ptr -9 input = dword ptr 8 push ebp mov ebp, esp sub esp, 18h jmp short loc_8048410 loc_804840C: add [ebp+input], 4 loc_8048410: call ___ctype_b_loc mov edx, [eax] mov eax, [ebp+input] mov eax, [eax] add eax, eax lea eax, [edx+eax] movzx eax, word ptr [eax] movzx eax, ax and eax, 2000h test eax, eax jnz short loc_804840C mov eax, [ebp+input] mov eax, [eax] mov [ebp+var_9], al cmp [ebp+var_9], '+' jz short loc_8048444 cmp [ebp+var_9], '-' jnz short loc_8048448 loc_8048444: add [ebp+input], 4 loc_8048448: mov [ebp+var_10], 0 jmp short loc_8048471 loc_8048451: mov edx, [ebp+var_10] mov eax, edx shl eax, 2 add eax, edx add eax, eax mov edx, eax mov eax, [ebp+input] mov eax, [eax] lea eax, [edx+eax] sub eax, 30h mov [ebp+var_10], eax add [ebp+input], 4 loc_8048471: call ___ctype_b_loc mov edx, [eax] mov eax, [ebp+input] mov eax, [eax] add eax, eax lea eax, [edx+eax] movzx eax, word ptr [eax] movzx eax, ax and eax, 800h test eax, eax jnz short loc_8048451 cmp [ebp+var_9], 2Dh jnz short loc_804849A neg [ebp+var_10] loc_804849A: mov eax, [ebp+var_10] leave retn _f endp
Ответ: atoi()
Исходник на Си:
3
Это также стандартная функция из библиотек Си, а вернее, две функции, работающие в паре. Исходник взят из MSVC 2010 и немного переделан.
Суть переделки в том, что эта функция может корректно работать в multi-threaded environment, а я, для упрощения (или запутывания) убрал это.
Скомпилировано в MSVC 2010 с флагом (/Ox).
_BSS SEGMENT _v DD 01H DUP (?) _BSS ENDS _TEXT SEGMENT _s$ = 8 ; size = 4 f1 PROC push ebp mov ebp, esp mov eax, DWORD PTR _s$[ebp] mov DWORD PTR _v, eax pop ebp ret 0 f1 ENDP _TEXT ENDS PUBLIC f2 _TEXT SEGMENT f2 PROC push ebp mov ebp, esp mov eax, DWORD PTR _v imul eax, 214013 ; 000343fdH add eax, 2531011 ; 00269ec3H mov DWORD PTR _v, eax mov eax, DWORD PTR _v shr eax, 16 ; 00000010H and eax, 32767 ; 00007fffH pop ebp ret 0 f2 ENDP _TEXT ENDS END
То же скомпилировано при помощи GCC 4.4.1:
public f1 f1 proc near arg_0 = dword ptr 8 push ebp mov ebp, esp mov eax, [ebp+arg_0] mov ds:v, eax pop ebp retn f1 endp public f2 f2 proc near push ebp mov ebp, esp mov eax, ds:v imul eax, 343FDh add eax, 269EC3h mov ds:v, eax mov eax, ds:v shr eax, 10h and eax, 7FFFh pop ebp retn f2 endp bss segment dword public 'BSS' use32 assume cs:_bss dd ? bss ends
Ответ: srand() / rand()
Исходник на Си:
4
Это стандартная функция из библиотек Си. Исходник взят из MSVC 2010. Скомпилировано в MSVC 2010 с флагом (/Ox).
PUBLIC _f _TEXT SEGMENT _arg1$ = 8 ; size = 4 _arg2$ = 12 ; size = 4 _f PROC push esi mov esi, DWORD PTR _arg1$[esp] push edi mov edi, DWORD PTR _arg2$[esp+4] cmp BYTE PTR [edi], 0 mov eax, esi je SHORT $LN7@f mov dl, BYTE PTR [esi] push ebx test dl, dl je SHORT $LN4@f sub esi, edi npad 6 $LL5@f: mov ecx, edi test dl, dl je SHORT $LN2@f $LL3@f: mov dl, BYTE PTR [ecx] test dl, dl je SHORT $LN14@f movsx ebx, BYTE PTR [esi+ecx] movsx edx, dl sub ebx, edx jne SHORT $LN2@f ; Line 50 inc ecx cmp BYTE PTR [esi+ecx], bl jne SHORT $LL3@f $LN2@f: cmp BYTE PTR [ecx], 0 je SHORT $LN14@f mov dl, BYTE PTR [eax+1] inc eax inc esi test dl, dl jne SHORT $LL5@f ; Line 58 xor eax, eax pop ebx pop edi pop esi ; Line 60 ret 0 _f ENDP _TEXT ENDS END
То же скомпилировано при помощи GCC 4.4.1:
public f f proc near var_C = dword ptr -0Ch var_8 = dword ptr -8 var_4 = dword ptr -4 arg_0 = dword ptr 8 arg_4 = dword ptr 0Ch push ebp mov ebp, esp sub esp, 10h mov eax, [ebp+arg_0] mov [ebp+var_4], eax mov eax, [ebp+arg_4] movzx eax, byte ptr [eax] test al, al jnz short loc_8048443 mov eax, [ebp+arg_0] jmp short locret_8048453 loc_80483F4: mov eax, [ebp+var_4] mov [ebp+var_8], eax mov eax, [ebp+arg_4] mov [ebp+var_C], eax jmp short loc_804840A loc_8048402: add [ebp+var_8], 1 add [ebp+var_C], 1 loc_804840A: mov eax, [ebp+var_8] movzx eax, byte ptr [eax] test al, al jz short loc_804842E mov eax, [ebp+var_C] movzx eax, byte ptr [eax] test al, al jz short loc_804842E mov eax, [ebp+var_8] movzx edx, byte ptr [eax] mov eax, [ebp+var_C] movzx eax, byte ptr [eax] cmp dl, al jz short loc_8048402 loc_804842E: mov eax, [ebp+var_C] movzx eax, byte ptr [eax] test al, al jnz short loc_804843D mov eax, [ebp+var_4] jmp short locret_8048453 loc_804843D: add [ebp+var_4], 1 jmp short loc_8048444 loc_8048443: nop loc_8048444: mov eax, [ebp+var_4] movzx eax, byte ptr [eax] test al, al jnz short loc_80483F4 mov eax, 0 locret_8048453: leave retn f endp
Ответ: strstr()
Исходник на Си:
5
Задача, скорее, на эрудицию, нежели на чтение кода.
Функция взята из OpenWatcom. Скомпилировано в MSVC 2010 с флагом (/Ox).
_DATA SEGMENT COMM __v:DWORD _DATA ENDS PUBLIC __real@3e45798ee2308c3a PUBLIC __real@4147ffff80000000 PUBLIC __real@4150017ec0000000 PUBLIC _f EXTRN __fltused:DWORD CONST SEGMENT __real@3e45798ee2308c3a DQ 03e45798ee2308c3ar ; 1e-008 __real@4147ffff80000000 DQ 04147ffff80000000r ; 3.14573e+006 __real@4150017ec0000000 DQ 04150017ec0000000r ; 4.19584e+006 CONST ENDS _TEXT SEGMENT _v1$ = -16 ; size = 8 _v2$ = -8 ; size = 8 _f PROC sub esp, 16 ; 00000010H fld QWORD PTR __real@4150017ec0000000 fstp QWORD PTR _v1$[esp+16] fld QWORD PTR __real@4147ffff80000000 fstp QWORD PTR _v2$[esp+16] fld QWORD PTR _v1$[esp+16] fld QWORD PTR _v1$[esp+16] fdiv QWORD PTR _v2$[esp+16] fmul QWORD PTR _v2$[esp+16] fsubp ST(1), ST(0) fcomp QWORD PTR __real@3e45798ee2308c3a fnstsw ax test ah, 65 ; 00000041H jne SHORT $LN1@f or DWORD PTR __v, 1 $LN1@f: add esp, 16 ; 00000010H ret 0 _f ENDP _TEXT ENDS END
Подсказка #1: Не забывайте что __v - глобальная переменная.
Подсказка #2: Эта функция вызывается startup-кодом перед вызовом main()
Ответ: Это проверка на наличие FDIV-ошибки в ранних процессорах Pentium
Исходник на Си:
6
Скомпилировано в MSVC 2010 с ключом /Ox
PUBLIC _f ; Function compile flags: /Ogtpy _TEXT SEGMENT _k0$ = -12 ; size = 4 _k3$ = -8 ; size = 4 _k2$ = -4 ; size = 4 _v$ = 8 ; size = 4 _k1$ = 12 ; size = 4 _k$ = 12 ; size = 4 _f PROC sub esp, 12 ; 0000000cH mov ecx, DWORD PTR _v$[esp+8] mov eax, DWORD PTR [ecx] mov ecx, DWORD PTR [ecx+4] push ebx push esi mov esi, DWORD PTR _k$[esp+16] push edi mov edi, DWORD PTR [esi] mov DWORD PTR _k0$[esp+24], edi mov edi, DWORD PTR [esi+4] mov DWORD PTR _k1$[esp+20], edi mov edi, DWORD PTR [esi+8] mov esi, DWORD PTR [esi+12] xor edx, edx mov DWORD PTR _k2$[esp+24], edi mov DWORD PTR _k3$[esp+24], esi lea edi, DWORD PTR [edx+32] $LL8@f: mov esi, ecx shr esi, 5 add esi, DWORD PTR _k1$[esp+20] mov ebx, ecx shl ebx, 4 add ebx, DWORD PTR _k0$[esp+24] sub edx, 1640531527 ; 61c88647H xor esi, ebx lea ebx, DWORD PTR [edx+ecx] xor esi, ebx add eax, esi mov esi, eax shr esi, 5 add esi, DWORD PTR _k3$[esp+24] mov ebx, eax shl ebx, 4 add ebx, DWORD PTR _k2$[esp+24] xor esi, ebx lea ebx, DWORD PTR [edx+eax] xor esi, ebx add ecx, esi dec edi jne SHORT $LL8@f mov edx, DWORD PTR _v$[esp+20] pop edi pop esi mov DWORD PTR [edx], eax mov DWORD PTR [edx+4], ecx pop ebx add esp, 12 ; 0000000cH ret 0 _f ENDP
Подсказка: Если погуглить применяемую здесь константу, это может помочь.
Ответ: Шифрование алгоритмом TEA (Tiny Encryption Algorithm)
Исходник на Си:
7
Это взята функция из ядра Linux 2.6.
Скомпилировано в MSVC 2010 с опцией /Ox:
_table db 000h, 080h, 040h, 0c0h, 020h, 0a0h, 060h, 0e0h db 010h, 090h, 050h, 0d0h, 030h, 0b0h, 070h, 0f0h db 008h, 088h, 048h, 0c8h, 028h, 0a8h, 068h, 0e8h db 018h, 098h, 058h, 0d8h, 038h, 0b8h, 078h, 0f8h db 004h, 084h, 044h, 0c4h, 024h, 0a4h, 064h, 0e4h db 014h, 094h, 054h, 0d4h, 034h, 0b4h, 074h, 0f4h db 00ch, 08ch, 04ch, 0cch, 02ch, 0ach, 06ch, 0ech db 01ch, 09ch, 05ch, 0dch, 03ch, 0bch, 07ch, 0fch db 002h, 082h, 042h, 0c2h, 022h, 0a2h, 062h, 0e2h db 012h, 092h, 052h, 0d2h, 032h, 0b2h, 072h, 0f2h db 00ah, 08ah, 04ah, 0cah, 02ah, 0aah, 06ah, 0eah db 01ah, 09ah, 05ah, 0dah, 03ah, 0bah, 07ah, 0fah db 006h, 086h, 046h, 0c6h, 026h, 0a6h, 066h, 0e6h db 016h, 096h, 056h, 0d6h, 036h, 0b6h, 076h, 0f6h db 00eh, 08eh, 04eh, 0ceh, 02eh, 0aeh, 06eh, 0eeh db 01eh, 09eh, 05eh, 0deh, 03eh, 0beh, 07eh, 0feh db 001h, 081h, 041h, 0c1h, 021h, 0a1h, 061h, 0e1h db 011h, 091h, 051h, 0d1h, 031h, 0b1h, 071h, 0f1h db 009h, 089h, 049h, 0c9h, 029h, 0a9h, 069h, 0e9h db 019h, 099h, 059h, 0d9h, 039h, 0b9h, 079h, 0f9h db 005h, 085h, 045h, 0c5h, 025h, 0a5h, 065h, 0e5h db 015h, 095h, 055h, 0d5h, 035h, 0b5h, 075h, 0f5h db 00dh, 08dh, 04dh, 0cdh, 02dh, 0adh, 06dh, 0edh db 01dh, 09dh, 05dh, 0ddh, 03dh, 0bdh, 07dh, 0fdh db 003h, 083h, 043h, 0c3h, 023h, 0a3h, 063h, 0e3h db 013h, 093h, 053h, 0d3h, 033h, 0b3h, 073h, 0f3h db 00bh, 08bh, 04bh, 0cbh, 02bh, 0abh, 06bh, 0ebh db 01bh, 09bh, 05bh, 0dbh, 03bh, 0bbh, 07bh, 0fbh db 007h, 087h, 047h, 0c7h, 027h, 0a7h, 067h, 0e7h db 017h, 097h, 057h, 0d7h, 037h, 0b7h, 077h, 0f7h db 00fh, 08fh, 04fh, 0cfh, 02fh, 0afh, 06fh, 0efh db 01fh, 09fh, 05fh, 0dfh, 03fh, 0bfh, 07fh, 0ffh f proc near arg_0 = dword ptr 4 mov edx, [esp+arg_0] movzx eax, dl movzx eax, _table[eax] mov ecx, edx shr edx, 8 movzx edx, dl movzx edx, _table[edx] shl ax, 8 movzx eax, ax or eax, edx shr ecx, 10h movzx edx, cl movzx edx, _table[edx] shr ecx, 8 movzx ecx, cl movzx ecx, _table[ecx] shl dx, 8 movzx edx, dx shl eax, 10h or edx, ecx or eax, edx retn f endp
Подсказка: Таблица содержит зараннее вычисленные значения. Можно было бы обойтись и без нее, но тогда функция работала бы чуть медленнее.
Ответ: Эта функция переставляет все биты в 32-битном слове наоборот. Это lib/bitrev.c
Исходник на Си:
8
Скомпилировано в MSVC 2010 с опцией /O1 (minimize space):
_a$ = 8 ; size = 4 _b$ = 12 ; size = 4 _c$ = 16 ; size = 4 ?s@@YAXPAN00@Z PROC ; s, COMDAT mov eax, DWORD PTR _b$[esp-4] mov ecx, DWORD PTR _a$[esp-4] mov edx, DWORD PTR _c$[esp-4] push esi push edi sub ecx, eax sub edx, eax mov edi, 200 ; 000000c8H $LL6@s: push 100 ; 00000064H pop esi $LL3@s: fld QWORD PTR [ecx+eax] fadd QWORD PTR [eax] fstp QWORD PTR [edx+eax] add eax, 8 dec esi jne SHORT $LL3@s dec edi jne SHORT $LL6@s pop edi pop esi ret 0 ?s@@YAXPAN00@Z ENDP ; s
Ответ: Сложение двух матриц размером 100 на 200 элементов типа double
Исходник на Си++:
9
Скомпилировано в MSVC 2010 с опцией /O1 (minimize space):
tv315 = -8 ; size = 4 tv291 = -4 ; size = 4 _a$ = 8 ; size = 4 _b$ = 12 ; size = 4 _c$ = 16 ; size = 4 ?m@@YAXPAN00@Z PROC ; m, COMDAT push ebp mov ebp, esp push ecx push ecx mov edx, DWORD PTR _a$[ebp] push ebx mov ebx, DWORD PTR _c$[ebp] push esi mov esi, DWORD PTR _b$[ebp] sub edx, esi push edi sub esi, ebx mov DWORD PTR tv315[ebp], 100 ; 00000064H $LL9@m: mov eax, ebx mov DWORD PTR tv291[ebp], 300 ; 0000012cH $LL6@m: fldz lea ecx, DWORD PTR [esi+eax] fstp QWORD PTR [eax] mov edi, 200 ; 000000c8H $LL3@m: dec edi fld QWORD PTR [ecx+edx] fmul QWORD PTR [ecx] fadd QWORD PTR [eax] fstp QWORD PTR [eax] jne SHORT $LL3@m add eax, 8 dec DWORD PTR tv291[ebp] jne SHORT $LL6@m add ebx, 800 ; 00000320H dec DWORD PTR tv315[ebp] jne SHORT $LL9@m pop edi pop esi pop ebx leave ret 0 ?m@@YAXPAN00@Z ENDP ; m
Ответ: Умножение двух матриц размерами 100*200 и 100*300 элементов типа double, результат: матрица 100*300
Исходник на Си++:
10
Если это скомпилировать и запустить, появится некоторое число. Откуда оно берется? Откуда оно берется если скомпилировать в MSVC с оптимизациями (/OX)?
#include <stdio.h> int main() { printf ("%d\n"); return 0; };
Средний уровень
1
Довольно известный алгоритм, также включен в стандартную библиотеку Си. Исходник взят из glibc 2.11.1. Скомпилирован в GCC 4.4.1 с ключем -Os (оптимизация по размеру кода). Листинг сделан дизассемблером IDA 4.9 из elf-файла созданным GCC и линкером.
Для тех кто хочет использовать IDA в процессе изучения, вот здесь лежит elf и idb файл, который можно открыть при помощи бесплатой IDA 4.9:
http://conus.info/RE-tasks/middle/1/
f proc near var_150 = dword ptr -150h var_14C = dword ptr -14Ch var_13C = dword ptr -13Ch var_138 = dword ptr -138h var_134 = dword ptr -134h var_130 = dword ptr -130h var_128 = dword ptr -128h var_124 = dword ptr -124h var_120 = dword ptr -120h var_11C = dword ptr -11Ch var_118 = dword ptr -118h var_114 = dword ptr -114h var_110 = dword ptr -110h var_C = dword ptr -0Ch arg_0 = dword ptr 8 arg_4 = dword ptr 0Ch arg_8 = dword ptr 10h arg_C = dword ptr 14h arg_10 = dword ptr 18h push ebp mov ebp, esp push edi push esi push ebx sub esp, 14Ch mov ebx, [ebp+arg_8] cmp [ebp+arg_4], 0 jz loc_804877D cmp [ebp+arg_4], 4 lea eax, ds:0[ebx*4] mov [ebp+var_130], eax jbe loc_804864C mov eax, [ebp+arg_4] mov ecx, ebx mov esi, [ebp+arg_0] lea edx, [ebp+var_110] neg ecx mov [ebp+var_118], 0 mov [ebp+var_114], 0 dec eax imul eax, ebx add eax, [ebp+arg_0] mov [ebp+var_11C], edx mov [ebp+var_134], ecx mov [ebp+var_124], eax lea eax, [ebp+var_118] mov [ebp+var_14C], eax mov [ebp+var_120], ebx loc_8048433: ; CODE XREF: f+28C�j mov eax, [ebp+var_124] xor edx, edx push edi push [ebp+arg_10] sub eax, esi div [ebp+var_120] push esi shr eax, 1 imul eax, [ebp+var_120] lea edx, [esi+eax] push edx mov [ebp+var_138], edx call [ebp+arg_C] add esp, 10h mov edx, [ebp+var_138] test eax, eax jns short loc_8048482 xor eax, eax loc_804846D: ; CODE XREF: f+CC�j mov cl, [edx+eax] mov bl, [esi+eax] mov [edx+eax], bl mov [esi+eax], cl inc eax cmp [ebp+var_120], eax jnz short loc_804846D loc_8048482: ; CODE XREF: f+B5�j push ebx push [ebp+arg_10] mov [ebp+var_138], edx push edx push [ebp+var_124] call [ebp+arg_C] mov edx, [ebp+var_138] add esp, 10h test eax, eax jns short loc_80484F6 mov ecx, [ebp+var_124] xor eax, eax loc_80484AB: ; CODE XREF: f+10D�j movzx edi, byte ptr [edx+eax] mov bl, [ecx+eax] mov [edx+eax], bl mov ebx, edi mov [ecx+eax], bl inc eax cmp [ebp+var_120], eax jnz short loc_80484AB push ecx push [ebp+arg_10] mov [ebp+var_138], edx push esi push edx call [ebp+arg_C] add esp, 10h mov edx, [ebp+var_138] test eax, eax jns short loc_80484F6 xor eax, eax loc_80484E1: ; CODE XREF: f+140�j mov cl, [edx+eax] mov bl, [esi+eax] mov [edx+eax], bl mov [esi+eax], cl inc eax cmp [ebp+var_120], eax jnz short loc_80484E1 loc_80484F6: ; CODE XREF: f+ED�j ; f+129�j mov eax, [ebp+var_120] mov edi, [ebp+var_124] add edi, [ebp+var_134] lea ebx, [esi+eax] jmp short loc_8048513 ; --------------------------------------------------------------------------- loc_804850D: ; CODE XREF: f+17B�j add ebx, [ebp+var_120] loc_8048513: ; CODE XREF: f+157�j ; f+1F9�j push eax push [ebp+arg_10] mov [ebp+var_138], edx push edx push ebx call [ebp+arg_C] add esp, 10h mov edx, [ebp+var_138] test eax, eax jns short loc_8048537 jmp short loc_804850D ; --------------------------------------------------------------------------- loc_8048531: ; CODE XREF: f+19D�j add edi, [ebp+var_134] loc_8048537: ; CODE XREF: f+179�j push ecx push [ebp+arg_10] mov [ebp+var_138], edx push edi push edx call [ebp+arg_C] add esp, 10h mov edx, [ebp+var_138] test eax, eax js short loc_8048531 cmp ebx, edi jnb short loc_8048596 xor eax, eax mov [ebp+var_128], edx loc_804855F: ; CODE XREF: f+1BE�j mov cl, [ebx+eax] mov dl, [edi+eax] mov [ebx+eax], dl mov [edi+eax], cl inc eax cmp [ebp+var_120], eax jnz short loc_804855F mov edx, [ebp+var_128] cmp edx, ebx jnz short loc_8048582 mov edx, edi jmp short loc_8048588 ; --------------------------------------------------------------------------- loc_8048582: ; CODE XREF: f+1C8�j cmp edx, edi jnz short loc_8048588 mov edx, ebx loc_8048588: ; CODE XREF: f+1CC�j ; f+1D0�j add ebx, [ebp+var_120] add edi, [ebp+var_134] jmp short loc_80485AB ; --------------------------------------------------------------------------- loc_8048596: ; CODE XREF: f+1A1�j jnz short loc_80485AB mov ecx, [ebp+var_134] mov eax, [ebp+var_120] lea edi, [ebx+ecx] add ebx, eax jmp short loc_80485B3 ; --------------------------------------------------------------------------- loc_80485AB: ; CODE XREF: f+1E0�j ; f:loc_8048596�j cmp ebx, edi jbe loc_8048513 loc_80485B3: ; CODE XREF: f+1F5�j mov eax, edi sub eax, esi cmp eax, [ebp+var_130] ja short loc_80485EB mov eax, [ebp+var_124] mov esi, ebx sub eax, ebx cmp eax, [ebp+var_130] ja short loc_8048634 sub [ebp+var_11C], 8 mov edx, [ebp+var_11C] mov ecx, [edx+4] mov esi, [edx] mov [ebp+var_124], ecx jmp short loc_8048634 ; --------------------------------------------------------------------------- loc_80485EB: ; CODE XREF: f+209�j mov edx, [ebp+var_124] sub edx, ebx cmp edx, [ebp+var_130] jbe short loc_804862E cmp eax, edx mov edx, [ebp+var_11C] lea eax, [edx+8] jle short loc_8048617 mov [edx], esi mov esi, ebx mov [edx+4], edi mov [ebp+var_11C], eax jmp short loc_8048634 ; --------------------------------------------------------------------------- loc_8048617: ; CODE XREF: f+252�j mov ecx, [ebp+var_11C] mov [ebp+var_11C], eax mov [ecx], ebx mov ebx, [ebp+var_124] mov [ecx+4], ebx loc_804862E: ; CODE XREF: f+245�j mov [ebp+var_124], edi loc_8048634: ; CODE XREF: f+21B�j ; f+235�j ... mov eax, [ebp+var_14C] cmp [ebp+var_11C], eax ja loc_8048433 mov ebx, [ebp+var_120] loc_804864C: ; CODE XREF: f+2A�j mov eax, [ebp+arg_4] mov ecx, [ebp+arg_0] add ecx, [ebp+var_130] dec eax imul eax, ebx add eax, [ebp+arg_0] cmp ecx, eax mov [ebp+var_120], eax jbe short loc_804866B mov ecx, eax loc_804866B: ; CODE XREF: f+2B3�j mov esi, [ebp+arg_0] mov edi, [ebp+arg_0] add esi, ebx mov edx, esi jmp short loc_80486A3 ; --------------------------------------------------------------------------- loc_8048677: ; CODE XREF: f+2F1�j push eax push [ebp+arg_10] mov [ebp+var_138], edx mov [ebp+var_13C], ecx push edi push edx call [ebp+arg_C] add esp, 10h mov edx, [ebp+var_138] mov ecx, [ebp+var_13C] test eax, eax jns short loc_80486A1 mov edi, edx loc_80486A1: ; CODE XREF: f+2E9�j add edx, ebx loc_80486A3: ; CODE XREF: f+2C1�j cmp edx, ecx jbe short loc_8048677 cmp edi, [ebp+arg_0] jz loc_8048762 xor eax, eax loc_80486B2: ; CODE XREF: f+313�j mov ecx, [ebp+arg_0] mov dl, [edi+eax] mov cl, [ecx+eax] mov [edi+eax], cl mov ecx, [ebp+arg_0] mov [ecx+eax], dl inc eax cmp ebx, eax jnz short loc_80486B2 jmp loc_8048762 ; --------------------------------------------------------------------------- loc_80486CE: ; CODE XREF: f+3C3�j lea edx, [esi+edi] jmp short loc_80486D5 ; --------------------------------------------------------------------------- loc_80486D3: ; CODE XREF: f+33B�j add edx, edi loc_80486D5: ; CODE XREF: f+31D�j push eax push [ebp+arg_10] mov [ebp+var_138], edx push edx push esi call [ebp+arg_C] add esp, 10h mov edx, [ebp+var_138] test eax, eax js short loc_80486D3 add edx, ebx cmp edx, esi mov [ebp+var_124], edx jz short loc_804876F mov edx, [ebp+var_134] lea eax, [esi+ebx] add edx, eax mov [ebp+var_11C], edx jmp short loc_804875B ; --------------------------------------------------------------------------- loc_8048710: ; CODE XREF: f+3AA�j mov cl, [eax] mov edx, [ebp+var_11C] mov [ebp+var_150], eax mov byte ptr [ebp+var_130], cl mov ecx, eax jmp short loc_8048733 ; --------------------------------------------------------------------------- loc_8048728: ; CODE XREF: f+391�j mov al, [edx+ebx] mov [ecx], al mov ecx, [ebp+var_128] loc_8048733: ; CODE XREF: f+372�j mov [ebp+var_128], edx add edx, edi mov eax, edx sub eax, edi cmp [ebp+var_124], eax jbe short loc_8048728 mov dl, byte ptr [ebp+var_130] mov eax, [ebp+var_150] mov [ecx], dl dec [ebp+var_11C] loc_804875B: ; CODE XREF: f+35A�j dec eax cmp eax, esi jnb short loc_8048710 jmp short loc_804876F ; --------------------------------------------------------------------------- loc_8048762: ; CODE XREF: f+2F6�j ; f+315�j mov edi, ebx neg edi lea ecx, [edi-1] mov [ebp+var_134], ecx loc_804876F: ; CODE XREF: f+347�j ; f+3AC�j add esi, ebx cmp esi, [ebp+var_120] jbe loc_80486CE loc_804877D: ; CODE XREF: f+13�j lea esp, [ebp-0Ch] pop ebx pop esi pop edi pop ebp retn f endp
Подсказка #1: В этом коде есть одна особенность, по которой можно значительносузить поиск функции в glibc
Ответ: Особенность - это вызов callback-функции, указатель на которую передается в четвертом аргументе. Это quicksort()
Исходник на Си:
crackme / keygenme
Несколько моих keygenme: