Сейчас на форуме: zds, UniSoft (+5 невидимых)

 eXeL@B —› Программирование —› _PadLeft прототип функции
Посл.ответ Сообщение


Ранг: 469.0 (мудрец), 100thx
Активность: 0.250
Статус: Участник
[www.AHTeam.org]

Создано: 29 апреля 2013 21:10 · Поправил: KingSise
· Личное сообщение · #1

Возникла вот у меня сложность с одной функцией (dll в аттаче)

Сама длл написана на борланд делфи, реверсю функцию ibe_PadLeft

По идеи она должна принимать всего 2 параметра: строку и то, что к ней с лева нужно добавить, а она принимает аж 6(!) Может кто со свежей головой поможет с прототипом?

Code:
  1. int __usercall ibe_PadLeft<eax>(int a1<ebx>, int a2<edi>, int a3<esi>, int a4, int a5, int a6)
  2. {
  3.   int v6; // eax@1
  4.   int v7; // ecx@1
  5.   int v8; // ebx@1
  6.   unsigned __int8 v9; // of@1
  7.   int v10; // ebx@1
  8.   int v11; // ebx@2
  9.   int (__cdecl *v12)(int, int, int); // ecx@4
  10.   unsigned int v14; // [sp-18h] [bp-20h]@1
  11.   int (__cdecl *v15)(int, int, int); // [sp-14h] [bp-1Ch]@1
  12.   int (__cdecl *v16)(int, int, int); // [sp-10h] [bp-18h]@1
  13.   int v17; // [sp-Ch] [bp-14h]@1
  14.   int v18; // [sp-8h] [bp-10h]@1
  15.   int v19; // [sp-4h] [bp-Ch]@1
  16.   int v20; // [sp+0h] [bp-8h]@1
  17.   int v21; // [sp+4h] [bp-4h]@1
  18.   int v22; // [sp+8h] [bp+0h]@1
  19.  
  20.   v21 = 0;
  21.   v20 = 0;
  22.   v19 = a1;
  23.   v18 = a3;
  24.   v17 = a2;
  25.   v16 = (int (__cdecl *)(int, int, int))&v22;
  26.   v15 = loc_40EB48;
  27.   v14 = __readfsdword(0);
  28.   __writefsdword(0, (unsigned int)&v14);
  29.   sub_405670(0, a4);
  30.   sub_405670(0, a5);
  31.   v6 = sub_40A92C();
  32.   v8 = *(_DWORD *)a6 - 1;
  33.   v9 = __OFSUB__(v8, v6);
  34.   v10 = v8 - v6;
  35.   if ( !(v10 < 0 ^ v9) )
  36.   {
  37.     v11 = v10 + 1;
  38.     do
  39.     {
  40.       sub_4057D4(v21, v20);
  41.       --v11;
  42.     }
  43.     while ( v11 );
  44.   }
  45.   sub_40AA18(v7, v21);
  46.   v12 = v16;
  47.   __writefsdword(0, v14);
  48.   v16 = loc_40EB4F;
  49.   return sub_405420(v12, 2);
  50. }



в длл

Code:
  1. 00B8EAC4 B>/$  55                          PUSH EBP
  2. 00B8EAC5   |.  8BEC                        MOV EBP, ESP
  3. 00B8EAC7   |.  6A 00                       PUSH 0x0
  4. 00B8EAC9   |.  6A 00                       PUSH 0x0
  5. 00B8EACB   |.  53                          PUSH EBX
  6. 00B8EACC   |.  56                          PUSH ESI
  7. 00B8EACD   |.  57                          PUSH EDI
  8. 00B8EACE   |.  8B75 08                     MOV ESI, [ARG.1]
  9. 00B8EAD1   |.  33C0                        XOR EAX, EAX
  10. 00B8EAD3   |.  55                          PUSH EBP
  11. 00B8EAD4   |.  68 48EBB800                 PUSH BizerbaU.00B8EB48
  12. 00B8EAD9   |.  64:FF30                     PUSH DWORD PTR FS:[EAX]
  13. 00B8EADC   |.  64:8920                     MOV DWORD PTR FS:[EAX], ESP
  14. 00B8EADF   |.  8BFE                        MOV EDI, ESI
  15. 00B8EAE1   |.  8D45 FC                     LEA EAX, [LOCAL.1]
  16. 00B8EAE4   |.  8BD6                        MOV EDX, ESI
  17. 00B8EAE6   |.  B9 00000000                 MOV ECX, 0x0
  18. 00B8EAEB   |.  E8 806BFFFF                 CALL BizerbaU.00B85670
  19. 00B8EAF0   |.  8D45 F8                     LEA EAX, [LOCAL.2]
  20. 00B8EAF3   |.  8B55 0C                     MOV EDX, [ARG.2]
  21. 00B8EAF6   |.  B9 00000000                 MOV ECX, 0x0
  22. 00B8EAFB   |.  E8 706BFFFF                 CALL BizerbaU.00B85670
  23. 00B8EB00   |.  8BC6                        MOV EAX, ESI
  24. 00B8EB02   |.  E8 25BEFFFF                 CALL BizerbaU.00B8A92C
  25. 00B8EB07   |.  8B5D 10                     MOV EBX, [ARG.3]
  26. 00B8EB0A   |.  8B1B                        MOV EBX, DWORD PTR DS:[EBX]
  27. 00B8EB0C   |.  4B                          DEC EBX
  28. 00B8EB0D   |.  2BD8                        SUB EBX, EAX
  29. 00B8EB0F   |.  7C 12                       JL SHORT BizerbaU.00B8EB23
  30. 00B8EB11   |.  43                          INC EBX
  31. 00B8EB12   |>  8D45 FC                     /LEA EAX, [LOCAL.1]
  32. 00B8EB15   |.  8B4D FC                     |MOV ECX, [LOCAL.1]
  33. 00B8EB18   |.  8B55 F8                     |MOV EDX, [LOCAL.2]
  34. 00B8EB1B   |.  E8 B46CFFFF                 |CALL BizerbaU.00B857D4
  35. 00B8EB20   |.  4B                          |DEC EBX
  36. 00B8EB21   |.75 EF                       \JNZ SHORT BizerbaU.00B8EB12
  37. 00B8EB23   |>  8B55 FC                     MOV EDX, [LOCAL.1]
  38. 00B8EB26   |.  8BC6                        MOV EAX, ESI
  39. 00B8EB28   |.  E8 EBBEFFFF                 CALL BizerbaU.00B8AA18
  40. 00B8EB2D   |.  33C0                        XOR EAX, EAX
  41. 00B8EB2F   |.  5A                          POP EDX
  42. 00B8EB30   |.  59                          POP ECX
  43. 00B8EB31   |.  59                          POP ECX
  44. 00B8EB32   |.  64:8910                     MOV DWORD PTR FS:[EAX], EDX
  45. 00B8EB35   |.  68 4FEBB800                 PUSH BizerbaU.00B8EB4F
  46. 00B8EB3A   |>  8D45 F8                     LEA EAX, [LOCAL.2]
  47. 00B8EB3D   |.  BA 02000000                 MOV EDX, 0x2
  48. 00B8EB42   |.  E8 D968FFFF                 CALL BizerbaU.00B85420
  49. 00B8EB47   \.  C3                          RETN
  50.  


5236_29.04.2013_EXELAB.rU.tgz - BizerbaUDF.dll

-----
-=истина где-то рядом=-




Ранг: 301.4 (мудрец), 194thx
Активность: 0.170.01
Статус: Участник

Создано: 29 апреля 2013 22:01
· Личное сообщение · #2

Что мешает нажать Y и вбить
Code:
  1. int __stdcall ibe_PadLeft(int a4, int a5, int a6)





Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 29 апреля 2013 22:36
· Личное сообщение · #3

ида ошиблась.
int a1<ebx>, int a2<edi>, int a3<esi> - значения этих регистров не используются

они сохраняются:
# 00B8EACB PUSH EBX
# 00B8EACC PUSH ESI
# 00B8EACD PUSH EDI

и затираются:
# 00B8EACE MOV ESI, [ARG.1]
# 00B8EADF MOV EDI, ESI
# 00B8EB07 MOV EBX, [ARG.3]

так что остаётся всего три параметра, передающихся через стэк
что есть третий параметр - я так и не врубился

вот приблизительный псевдокод:
Code:
  1. arg1 equ [ebp+8]
  2. arg2 equ [ebp+C]
  3. arg3 equ [ebp+10]
  4.  
  5. var1 equ [ebp-4]
  6. var2 equ [ebp-8]
  7. var3 = [arg3]
  8.  
  9. @LStrFromPChar(var1, arg1);
  10. @LStrFromPChar(var2, arg2);
  11.  
  12. if (var3 - StrLen(arg1) >= 1)
  13. {
  14.          do      {@LStrCat3 (&var1, var2, var1);}
  15.          while (--var3)
  16. }
  17.  
  18. StrPCopy (arg1, var1);
  19.  
  20. return arg1;




Ранг: 72.1 (постоянный), 30thx
Активность: 0.050
Статус: Участник

Создано: 29 апреля 2013 22:49 · Поправил: yagello
· Личное сообщение · #4

Строки в ДЛЛ? Скорее всего PChar'ы с длинами, либо еще плюс счетчики ссылок. IBE,UDF - это не из библиотеки доступа к InterBase? Тогда можно и сорцы взять, они (должны быть куплены, но мы-то знаем) доступны. Третий параметр - длина максимальная?
А вообще по логике - дополнить слева до длины ХХХ символом YYY




Ранг: 469.0 (мудрец), 100thx
Активность: 0.250
Статус: Участник
[www.AHTeam.org]

Создано: 30 апреля 2013 02:14 · Поправил: KingSise
· Личное сообщение · #5

-=AkaBOSS=-,

спасибо, вроде разобрался, декларация выглядит вот так:

Code:
  1. Public Declare Function ibe_PadLeft Lib "BizerbaUDF.dll" (ByVal a1 As String, ByVal a2 As String, ByRef a3 As IntPtr) As String



или на С#
Code:
  1. [DllImport("BizerbaUDF.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
  2. public static extern string ibe_PadLeft(string a1, string a2, ref IntPtr a3);


Первый параметр - исходная строка, вторая - что будем дописывать слева. Третий параметр самый интересный, в нем у меня и была проблемко.

Это вроде как указатель на конец первой строки, причем его значение по модулю должно быть больше длинны первой строки. Тогда функция вернет результат (строку) и заодно перезапишет значение в памяти где хранилась исходная строка заменяемым символом.





Veliant пишет:
Что мешает нажать Y и вбить

Я немножко протупил, не спорю. Конечно же ничего не мешает. Сбил с толку последний параметр.



В общем я подключил библиотеку и она вроде как надо работает, пример в аттаче. Далее можно смотреть в отладчике, однако для меня все еще остается загадкой назначения этой функции. Если последний параметр на 1 больше длинны первой строки, то функция допишет символ в начало строки, если вызвать ее несколько раз - заменит посимвольно исходную строку...

6f58_30.04.2013_EXELAB.rU.tgz - Release.rar

-----
-=истина где-то рядом=-





Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 30 апреля 2013 02:49 · Поправил: -=AkaBOSS=-
· Личное сообщение · #6

хоть это и не проверяется явным образом, вторая строка, по-видимому, должна состоять
из одного символа, которым и будет выполняться паддинг исходной строки.
а третий параметр определяет, до какого размера эта строка должна быть расширена.

за каким чёртом оно нужно - большой вопрос, но раз кто-то не поленился написать - значит, была необходимость... наверное

ADD:
а что за софт эту длл долбит? может, есть смысл поискать примеры использования функции в нём?




Ранг: 469.0 (мудрец), 100thx
Активность: 0.250
Статус: Участник
[www.AHTeam.org]

Создано: 30 апреля 2013 02:55 · Поправил: KingSise
· Личное сообщение · #7

yagello пишет:
IBE,UDF - это не из библиотеки доступа к InterBase?

В общем да, библиотека работает с фаерберт. Исходников ее нет.



-=AkaBOSS=- пишет:
за каким чёртом оно нужно - большой вопрос

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

add
-=AkaBOSS=- пишет:
сть смысл поискать примеры использования функции в нём?



Вряд ли есть примеры. Как видно из названия длл, кодила ее вот эта фирма: www.bizerba.de Причем походу в приватном порядке. И исходниками с примерами она вряд ли поделится. Ноль результатов в гугле:


add

Зато яндекс результаты уже выдает:



add
WIN!!!!! Если длинна строки более 525 символов, функция падает. Проблема кажись решена.

-----
-=истина где-то рядом=-





Ранг: 307.9 (мудрец), 196thx
Активность: 0.180
Статус: Участник

Создано: 30 апреля 2013 03:20 · Поправил: mysterio
· Личное сообщение · #8

Догадка: Может оно должно так выглядеть ? Второй параметр до какой длины расширять Source. Просто в затирании строки нет смысла - если конечно это не делается специально.
Code:
  1. function PadLeftA(const Source: String; const Count: Cardinal; const c: AnsiChar): String;
  2. var
  3.   i, l: Cardinal;
  4.   p1, p2: PAnsiChar;
  5. begin
  6.   l := Length(Source);
  7.  
  8.   if Count > l then
  9.     begin
  10.       SetString(Result, nil, Count);
  11.       p2 := Pointer(Result);
  12.       i := Count - l;
  13.       repeat
  14.         Dec(i);
  15.         p2[i] := c;
  16.       until i = 0;
  17.  
  18.       if l > 0 then
  19.         begin
  20.           p1 := Pointer(Source);
  21.           Inc(p2, Count - l);
  22.           repeat
  23.             Dec(l);
  24.             p2[l] := p1[l];
  25.           until l = 0;
  26.         end;
  27.     end
  28.   else
  29.  
  30.     Result := Source;
  31. end;
  32.  
  33. //
  34. PadLeftA('abcde', 8, '#');
  35. Result = '###abcde'


-=AkaBOSS=-
Опередил ;)

-----
Don_t hate the cracker - hate the code.


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


Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 30 апреля 2013 03:26 · Поправил: -=AkaBOSS=-
· Личное сообщение · #9

KingSise пишет:
WIN!!!!! Если длинна строки более 525 символов, функция падает. Проблема кажись решена.

только сам хотел это отпостить))
да, действительно, если общая длина строки больше 525 символов,
после вызова StrPCopy затираются значения в стэке


KingSise пишет:
заменит посимвольно исходную строку

она не заменяет символы, а дописывает их в начало.
это при отображении почему-то не учитывается изменённая длина строки, и берутся только первые символы

KingSise пишет:
Вот и мне непонятно нах оно нужно

ну, могу только предположить, что эта функция используется при
форматированном выводе для выравнивания текста по правому краю.
этим же можно объяснить отсутствие проверки на длину второй строки,
а третий параметр - это общая ширина выходящей страницы.
таким образом, текст может выравниваться как угодно:
точками, пробелами, табуляцией, эскейп-последовательностями, &nbsp; и еще хрен знает чем

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


Ранг: 469.0 (мудрец), 100thx
Активность: 0.250
Статус: Участник
[www.AHTeam.org]

Создано: 01 мая 2013 15:16 · Поправил: KingSise
· Личное сообщение · #10

решил сделать что бы длл логировала параметры передаваемые в функцию, вроде бы все сделал, работает заебушечки, но только в отладчике. Как я понимаю это из за того, что длл грузится по разным адресам.

в аттаче пропатченная длл, cmdlog.exe - просто пишет в текстопыал параметры командной строки, PadLeft.exe - для теста функции.

сделал вроде все как положено: добавил секцию, в начале процедуры PadLeft сделал прыг на мой участок кода

Code:
  1. 0126EAC4 B>      JMP BizerbaU.01286005
  2. 0126EAC9         PUSH 0x0
  3. 0126EACB         PUSH EBX
  4. 0126EACC         PUSH ESI
  5. 0126EACD         PUSH EDI
  6.  


далее просто идет запуск логера с параметрами (упрошенный вариант)

Code:
  1. 01286007    .    PUSHAD
  2. 01286008    .    NOP
  3. 01286009    .    PUSHFD
  4. 0128600A    .    PUSH 0x0                                    ; /IsShown = 0x0
  5. 0128600C    .    PUSH 0x0                                    ; |DefDir = NULL
  6. 0128600E    .    PUSH DWORD PTR SS:[ESP+0x30]                ; |Parameters
  7. 01286012    .    PUSH BizerbaU.0128604E                      ; |FileName = "cmdlog.exe"
  8. 01286017    .    PUSH BizerbaU.01286049                      ; |Operation = "Open"
  9. 0128601C    .    PUSH 0x0                                    ; |hWnd = NULL
  10. 0128601E    .    CALL shell32.ShellExecuteA                  ; \ShellExecuteA
  11. 01286023    .    PUSH 0x0                                    ; /IsShown = 0x0
  12. 01286025    .    PUSH 0x0                                    ; |DefDir = NULL
  13. 01286027    .    PUSH DWORD PTR SS:[ESP+0x34]                ; |Parameters
  14. 0128602B    .    PUSH BizerbaU.0128604E                      ; |FileName = "cmdlog.exe"
  15. 01286030         PUSH BizerbaU.01286049                      ; |Operation = "Open"
  16. 01286035    .    PUSH 0x0                                    ; |hWnd = NULL
  17. 01286037    .    CALL shell32.ShellExecuteA                  ; \ShellExecuteA
  18. 0128603C         POPFD
  19. 0128603D         POPAD
  20. 0128603E    .    PUSH EBP
  21. 0128603F    .    MOV EBP, ESP
  22. 01286041    .    PUSH 0x0
  23. 01286043    .    JMP BizerbaU.0126EAC9
  24. 01286048    .    RETN
  25.  

Можно сделать и вот так, но опять же, работает ь под отладчиком.

Code:
  1.  
  2. pushad
  3. pushfd
  4.  
  5. push @dll
  6. call LoadLibraryA
  7.  
  8.  
  9. push eax  ;Save EAX
  10. push @dll
  11. CALL GetModuleHandleA  ;Dll Adress
  12. mov esi, eax
  13. push @Msg
  14. push esi
  15. CALL GetProcAddress   ;FuncAdress
  16. mov esi, eax
  17. pop eax
  18.  
  19.  
  20.  
  21. push 0
  22. push 0
  23. PUSH DWORD PTR SS:[ESP+0x30]
  24. push @file
  25. push @com
  26. push 0
  27. call esi
  28. ;call NEAR DWORD PTR DS:[0x012470C7]
  29.  
  30. push 0
  31. push 0
  32. PUSH DWORD PTR SS:[ESP+0x34]
  33. push @file
  34. push @com
  35. push 0
  36. call esi
  37. ;call NEAR DWORD PTR DS:[0x012470C7]
  38.  
  39.  
  40.  popfd
  41.  popad
  42.  
  43.   PUSH EBP
  44.  MOV EBP,ESP
  45.   PUSH 0x0
  46.   jmp 0122EAC9
  47.  
  48. ret
  49.  
  50. @com: "Open\0"
  51. @file: "cmdlog.exe\0"
  52. @dll: "shell32.dll\0"
  53. @Msg: "ShellExecuteA\0"




как бы мне все-таки запилить логирование?


98fb_01.05.2013_EXELAB.rU.tgz - test.rar

-----
-=истина где-то рядом=-




Ранг: 301.4 (мудрец), 194thx
Активность: 0.170.01
Статус: Участник

Создано: 01 мая 2013 15:42
· Личное сообщение · #11

Делов-то пересчитать два адреса для jmp'ов относительно ImageBase?!
Ну или затри информацию о релоках




Ранг: 469.0 (мудрец), 100thx
Активность: 0.250
Статус: Участник
[www.AHTeam.org]

Создано: 01 мая 2013 16:38
· Личное сообщение · #12

Veliant, что то у мну не особо выходит... Можно так то дллку подправить, типа наглядного примерчика?

-----
-=истина где-то рядом=-





Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 02 мая 2013 09:43 · Поправил: -=AkaBOSS=-
· Личное сообщение · #13

KingSise
у дллки же ведь есть в импорте GetModuleHandle\GetProcAddress
нужно сначала получить адрес ShellExecute, а потом уже вызывать её..
а то у меня что под отладчиком, что без него, вызовы одинаково идут куда-то в ntdll.dll

плюс ко всему - эти две константы счастья не добавляют:
KingSise пишет:
Code:
  1. 01286012    .    PUSH BizerbaU.0128604E                      ; |FileName = "cmdlog.exe"
  2. 01286017    .    PUSH BizerbaU.01286049 
  3. ...
  4. 0128602B    .    PUSH BizerbaU.0128604E                      ; |FileName = "cmdlog.exe"
  5. 01286030         PUSH BizerbaU.01286049

от них нужно избавиться

KingSise пишет:
Code:
  1. push @dll
  2. call LoadLibraryA
  3.   
  4. push eax  ;Save EAX
  5. push @dll
  6. CALL GetModuleHandleA  ;Dll Adress

LoadLibrary и так возвращает либо ноль, либо hModule. GetModuleHandle тут не нужен.

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

в общем, написал я свой вызов логгера.
у меня, вроде бы, работает (разве что cmdlog.exe временами падает при вызове getCommandLineArg)
в аттаче - исходник на фасме и пропатченная длл

28e6_02.05.2013_EXELAB.rU.tgz - dlltest.7z

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


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