Сейчас на форуме: asfa, _MBK_, Adler, bartolomeo (+9 невидимых)

 eXeL@B —› Вопросы новичков —› Перевернутая функция
Посл.ответ Сообщение

Ранг: 9.7 (гость)
Активность: 0.020
Статус: Участник

Создано: 02 сентября 2012 23:36
· Личное сообщение · #1

Имеется следующий код:

Code:
  1.          
  2.                  mov     eax,0x00686A14  
  3.                 //JMP           DWORD PTR DS:[0x006CC278]
  4.                  call      _EH_prolog 
  5.                 sub     esp, 0x18  
  6.                 push    ebx 
  7.                 push    esi  
  8.                 push    edi  
  9.                 xor     ebx, ebx 
  10.                 push   0x006CC64C  // Source  
  11.                 lea     ecx, [ebp-20]  
  12.                 mov     [ebp-4], ebx  
  13.                 mov     [ebp-20], ebx  
  14.                 call   DWORD PTR DS:[0x004018D6] 
  15.                 push    DWORD PTR SS:[EBP+0x1C]    // Source  
  16.                 lea     ecx, [ebp-20]  
  17.                 mov     byte ptr [ebp-4], 1  
  18.                 call   DWORD PTR DS:[0x004018D6]  
  19.                 lea     eax, [ebp-14]  
  20.                 push    eax  
  21.                 call   DWORD PTR DS:[0x00561299]


Я его переписал следующим образом:

Code:
  1. struct Struct_0040BBB6
  2. {
  3.     int *p;
  4.          int UnknownA[7];
  5.          DWORD sub_004018D6 (char*);
  6.  
  7. };
  8.  
  9. Struct_0040BBB6 *sc;
  10.  
  11. sc->p=sc->UnknownA;
  12. sc->UnknownA[0]=0;
  13. sc->UnknownA[7]=0;
  14. Game::sub_004018D6(&Game::offset_006CC64C);
  15.  
  16. sc->p=sc->UnknownA;
  17. sc->UnknownA[0]=1;
  18. Game::sub_004018D6(Source);
  19.  
  20. (DWORD)(Game::sub_00561299(sc->UnknownA[4]) + 4);


Но получается все наоборот. У меня начало массива там, где должен быть конец и наоборот. [ebp-14] - аргумент sub_00561299 должен быть равен 0, у меня там адрес... Указатель *р должен смотреть в конец массива - EBP -20, у меня в начало - LEA EDI,[ESI+4] (см ниже)

Вот вариант моего кода после компиляции:
Code:
  1.  INT my_0040BBB6@32(a1,a2,a3,a4,a5,Source,a7,a8)
  2. MOV EBP,ESP
  3. PUSH ESI
  4. MOV ESI,DWORD PTR SS:[ARG.6]
  5. PUSH EDI
  6. LEA EDI,[ESI+4]
  7. PUSH 6CC64C                              ; /Arg1 = 6CC64C
  8. MOV EAX,4018D6                           ; |Entry point
  9. MOV DWORD PTR DS:[ESI],EDI               ; |
  10. MOV DWORD PTR DS:[EDI],0                 ; |
  11. MOV DWORD PTR DS:[ESI+20],0              ; |
  12. CALL EAX                                 ; \004018D6
  13. MOV ECX,DWORD PTR SS:[ARG.6]
  14. PUSH ECX                                 ; /Arg1 => [ARG.6]
  15. MOV EDX,4018D6                           ; |Entry point
  16. MOV DWORD PTR DS:[ESI],EDI               ; |
  17. MOV DWORD PTR DS:[EDI],1                 ; |
  18. CALL EDX                                 ; \004018D6
  19. MOV EAX,DWORD PTR DS:[ESI+14]
  20. PUSH EAX                                 ; /Arg1
  21. MOV ECX,561299                           ; |Entry point
  22. CALL ECX                                 ; \00561299


Как можно заметить массивы похожи, с несколькими отличиями:

1. Мой массив сохраняется в ESI, оригинальный в EBP.
2. ESI+14 - четвертый элемент моего массива должен быть равен нулю, но это не так. Элемент по адресу [EBP-14]=0 в оригинале.
3. P* - находится по адресу 0х00, и запись массива начинается по этой причине с 0х04, что обрубает первое слово из строки, которая там должна быть записана.

В общем, был бы благодарен за правильный пример реверснутого кода выше. Спасибо.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 02 сентября 2012 23:52
· Личное сообщение · #2

нифига не понял

Code:
  1. struct Struct_0040BBB6
  2. {
  3.          DWORD sub_004018D6 (char*);
  4. };

вызов
Game::sub_004018D6(&Game::offset_006CC64C);
а нафига тогда sc инициализировать если вы его не используете,
да и вообще.
если смысл заменить функцию начинающуюся с "sub esp, 0x18"
так и сделайте ее в IDA как функцию, и запустив HexRays увидите как ее заменить



Ранг: 9.7 (гость)
Активность: 0.020
Статус: Участник

Создано: 03 сентября 2012 00:42
· Личное сообщение · #3

reversecode пишет:
если смысл заменить функцию начинающуюся с "sub esp, 0x18"
так и сделайте ее в IDA как функцию, и запустив HexRays увидите как ее заменить


Да, смысл в этом. И как раз где-то с ее реверсингом я и накосячил. И кажется уже подозреваю где - у меня в sub_561299 передается адрес, а нужно - значение. Это по поводу пункта 2 в моем первом посте: ESI+14 - четвертый элемент моего массива должен быть равен нулю, но это не так. Элемент по адресу [EBP-14]=0 в оригинале.

В Hex получается следующее:

Code:
  1. int __stdcall sub_40BBB6(int a1, char a2, int a3, int a4, int a5, char *Source, int a7, int a8)
  2. {
  3.   int v8; // ecx@1
  4.   int v9; // edx@1
  5.   int v10; // eax@3
  6.   int v11; // esi@14
  7.   int v12; // edi@16
  8.   int v13; // esi@16
  9.   char v14; // al@18
  10.   int v15; // eax@21
  11.   int v17; // [sp+Ch] [bp-24h]@2
  12.   int v18; // [sp+10h] [bp-20h]@1
  13.   int v19; // [sp+14h] [bp-1Ch]@1
  14.   int v20; // [sp+1Ch] [bp-14h]@1
  15.   int v21; // [sp+2Ch] [bp-4h]@1
  16.  
  17.   v21 = 0;
  18.   v18 = 0;
  19.   sub_4018D6((char *)&Default);
  20.   LOBYTE(v21) = 1;
  21.   sub_4018D6(Source);
  22.   v8 = *(_DWORD *)(sub_561299(&v20) + 4);
  23.  
  24. ....


Sc нужно просто для использования структуры Struct_0040BBB6. Можно и без нее, но так удобнее ИМХО.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 03 сентября 2012 00:46
· Личное сообщение · #4

ничего там нельзя без,
потому что то обьектыные функции скорее всего
ecx передается - разве не видно???
в рее не правильно, потому что вы в функции не позаходили, рей не знает о втором аргументе,
точнее он первый только в ecx



Ранг: 9.7 (гость)
Активность: 0.020
Статус: Участник

Создано: 03 сентября 2012 00:54
· Личное сообщение · #5

reversecode пишет:
ecx передается - разве не видно???

Так и есть, прошу прощения.

Таким образом, в моем варианте первые два вызова:
Game::sub_004018D6(&Game::offset_006CC64C); и
Game::sub_004018D6(Source);

проходят нормально, только в первом случае со смещением на 4 по сравнению с оригиналом. Что есть неудобство номер раз.

А вот вызов (DWORD)(Game::sub_00561299(sc->UnknownA[4]) + 4);
не проходит вообще. Похоже, что это из-за того, что я с передаваемым аргументом накосячил.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 03 сентября 2012 00:59 · Поправил: reversecode
· Личное сообщение · #6

опять запутались с stdcall/cdecl ?
дайте лучше екзешник или что у вас там

скукота, я с платных ФО, да еще и таких как ниже, не качаю
потрудитесь в следующий раз пользоватся rghost или sendspace



Ранг: 9.7 (гость)
Активность: 0.020
Статус: Участник

Создано: 03 сентября 2012 01:08 · Поправил: Dim77
· Личное сообщение · #7

reversecode пишет:
опять запутались с stdcall/cdecl ?

Может быть...

Hex определяет sub_00561299 как stdcall. Я ее так и определил. Кстати, в IDA это функция near, не подскажете чему она соответствует?

Определение:
#define FUNC( name, address, ret_type, call_convention, args ) ret_type(call_convention * const name)args = (ret_type(call_convention *)args) address;

FUNC( sub_00561299, 0x00561299, DWORD, __stdcall, ( int) );

-->Ехе файл <--
-->Моя Dll <--

Странно, мне казалось, что этот ФО был указан в правилах сайта... К тому же у меня он бесплатный. Но не суть. Вот тоже самое, но на rghost

--> Моя Dll <--
-->Exe Файл <--




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 03 сентября 2012 01:59
· Личное сообщение · #8

__thiscall sub_4018D6
__stdcall sub_561299

Code:
  1. _complex_string *__thiscall compex_string_ctor_sub_4018D6(_complex_string *this, const char *stra2)
  2. {
  3.   size_t lenv2; // eax@5
  4.   _complex_string *this_; // [sp+0h] [bp-8h]@1
  5.  
  6.   this_ = this;
  7.   if ( this->pbuf_field_0 )
  8.   {
  9.     free_sub_401A58(this->pbuf_field_0);
  10.     this_->pbuf_field_0 = 0;
  11.   }
  12.   if ( stra2 && *stra2 )
  13.   {
  14.     lenv2 = strlen(stra2);
  15.     this_->pbuf_field_0 = malloc_sub_401A4B(lenv2 + 1);
  16.     strcpy((char *)this_->pbuf_field_0, stra2);
  17.   }
  18.   else
  19.   {
  20.     this_->pbuf_field_0 = 0;
  21.   }
  22.   return this_;
  23. }


Code:
  1. _complex_dword *__stdcall init_complex_from_struct_836FF8_sub_561299(_complex_dword *a1)
  2. {
  3.   a1->field_0 = 0;
  4.   a1->field_4 = 0;
  5.   operator_eq_sub_403CC5(a1, (int)&stru_836FF8);
  6.   return a1;
  7. }


Code:
  1. int __stdcall sub_40BBB6(int a1, char a2, int a3, int a4, int a5, const char *stra6, int a7, int a8)
  2. {
  3.   int ptrv8; // ecx@1
  4.   int v9; // edx@1
  5.   int v10; // eax@3
  6.   int v11; // esi@14
  7.   int v12; // edi@16
  8.   int v13; // esi@16
  9.   char v14; // al@18
  10.   int v15; // eax@21
  11.   int *v17; // [sp+Ch] [bp-24h]@2
  12.   _complex_string _ssvar_20; // [sp+10h] [bp-20h]@1
  13.   _complex_dword cmv19; // [sp+1Ch] [bp-14h]@1
  14.   int v20; // [sp+2Ch] [bp-4h]@1
  15.  
  16.   v20 = 0;
  17.   _ssvar_20.pbuf_field_0 = 0;
  18.   compex_string_ctor_sub_4018D6(&_ssvar_20, &byte_6CC64C);
  19.   LOBYTE(v20) = 1;
  20.   compex_string_ctor_sub_4018D6(&_ssvar_20, stra6);
  21.   ptrv8 = init_complex_from_struct_836FF8_sub_561299(&cmv19)->ptrfield_4;
  22.   LOBYTE(v20) = 2;
  23.   _ssvar_20.field_4 = sub_5613E1(ptrv8);
  24.   LOBYTE(v20) = 1;
  25.   sub_401943(&cmv19, 0);


| Сообщение посчитали полезным: Dim77

Ранг: 9.7 (гость)
Активность: 0.020
Статус: Участник

Создано: 03 сентября 2012 02:17
· Личное сообщение · #9

Кажется понял. Завтра перепишу свой код. Без переписывания функций __thiscall sub_4018D6
__stdcall sub_561299, ибо мне нужно их использовать такими, какие они есть. Ну, вызовы-то я понятно изменю. Спасибо.

А откуда этот код? Мой Нех версии 6.1 выдает то, что я привел выше. И там все было далеко все не так интересно...




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 03 сентября 2012 10:39
· Личное сообщение · #10

код из хекс рея 1.5 версии, который идет в комплекте с 6.1 ида,
уметь работать надо,
а не просто F5 жать



Ранг: 9.7 (гость)
Активность: 0.020
Статус: Участник

Создано: 05 сентября 2012 23:58 · Поправил: Dim77
· Личное сообщение · #11

Сделал, заработало . Вот вариант кода, если интересно. Если честно, то не заметил, где в реверсированном коде нужно использовать 2 структуры. Пока вполне хватило и одной. Они все равно идентичны.

В компилированном коде получилась одна лишняя строчка (по сравнению с оригиналом), которая я не понял, откуда вылезла.
ЗЫ Хмм, сейчас подумал, что она вылезла как раз из второй ненужной структуры...

Но пока код работает и вроде бы правильно. Точнее можно будет сказать, когда всю функцию полностью реверсну.

Code:
  1.  int __stdcall my_0040BBB6(int a1, char a2, int a3, int a4, int a5, char *Source, int a7, int a8)
  2. {
  3.  
  4. Struct_0040BBB6 *sc;
  5. Struct1_0040BBB6 *sc1;
  6.  
  7. sc->p=&(sc->UnknownH);
  8. sc->UnknownA=0;
  9. sc->UnknownH=0;
  10. Game::sub_004018D6(sc, &Game::offset_006CC64C);
  11.  
  12. sc->UnknownA=1;
  13. Game::sub_004018D6(sc, Source);
  14.  
  15. Game::sub_00561299(&(sc1)->UnknownE);


reversecode пишет:
уметь работать надо,
а не просто F5 жать

Ну, так учишься обычно постепенно. А если не знать, что там такая функциональность есть, то и искать ее не будешь




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 06 сентября 2012 00:04
· Личное сообщение · #12

Dim77 пишет:
Ну, так учишься обычно постепенно. А если не знать, что там такая функциональность есть, то и искать ее не будешь

об этом цветным по белому написано в хелпе на сайте хексрея,
и очень много всяких ильфаковских видео



Ранг: 9.7 (гость)
Активность: 0.020
Статус: Участник

Создано: 10 сентября 2012 12:29
· Личное сообщение · #13

reversecode пишет:
очень много всяких ильфаковских видео


Нашел несколько на сайте Hex-Rays. Больше пока не видел. Возможно, поиск не тем словам запускаю...




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 10 сентября 2012 13:47
· Личное сообщение · #14

hexblog.com там есть со вских семинаров



Ранг: 9.7 (гость)
Активность: 0.020
Статус: Участник

Создано: 19 сентября 2012 20:18 · Поправил: Dim77
· Личное сообщение · #15

Посмотрел материалы. Пока что не добрался до того же уровня детализации, что приведен выше у reversecode
Например, вычислить используемую структуру и то что их две а не одна, пока не удалось.

Подредактировал код. Даже в коде, приведенном reversecode не все до конца разобрано. Это не критицизм, а так оно и дoлжно быть, ибо все равно нужно проверять в дебагере, каким бы хорошим авто диссасемблинг ни был.

Например, строчка
Code:
  1. ptrv8 = init_complex_from_struct_836FF8_sub_561299(&cmv19)->ptrfield_4;
на самом деле выглядит:
Code:
  1. ptrv8 = init_complex_from_struct_836FF8_sub_561299(&(_ssvar_20->field_4))->ptrfield_1
ибо в 5-ом элементе (field_4) первой структуры находится элемент второй, а ptrfield_1 указывает на 2-ой (отстоящий на 0х04) элемент 2-ой структуры. Это в дебагере видно.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 20 сентября 2012 00:11
· Личное сообщение · #16

ptrv8 = init_complex_from_struct_836FF8_sub_561299(&(_ssvar_20->field_4))->ptrfield_1

помоему глупость
cmv19 стековая стуктура, откуда у вас там такая заумная конструкция взялась?
ну вообщем главное что бы у вас работало, idb я помоему уже грохнул, перепроверять лень


 eXeL@B —› Вопросы новичков —› Перевернутая функция
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати