Сейчас на форуме: cppasm, asfa (+7 невидимых)

 eXeL@B —› Вопросы новичков —› msvcr100.free
Посл.ответ Сообщение

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

Создано: 08 ноября 2016 00:33 · Поправил: zds
· Личное сообщение · #1

Здравствуйте
Есть прога dotNet. В ней есть dll (пусть будет dll1) mixed mode, которя является какбы прослойкой между програмой и другой нативной dll (dll2) отвечающей за лицензирование.
в dll1 есть Net функции например getSN,getDays и так далее, в которых идет вызов native функций dll1 и которые уже в свою очередь обращаются к dll2.
интересно, что в Net функциях dll1 все аргументы (1-2 строки) передаются в нативные функции dll1 через указатели и результат тоже указатель, который преобразуется результат фукнции - string, int, bool
что я сделал:
написал свою dll на делфи, добавил ее в импорт dll2. при запуске моя dll находит секцию кода dll1 и во всех интересующих меня нативных функциях в самом начале делает jump на мои функции, из которых я уже передаю нужный мне результат.
все работает отлично с функциями где результат int, string, bool
случился затык только с фукнцией где релультатом является List<string>

код такой
Code:
  1. List<string> list = new List<string>();
  2. basic_string<char,std::char_traits<char>,std::allocator<char> > basic_string<char,std::char_traits<char>,std::allocator<char> >;
  3. <Module>.std.basic_string<char,std::char_traits<char>,std::allocator<char> >.{ctor}(ref basic_string<char,std::char_traits<char>,std::allocator<char> >, (sbyte*)(&<Module>.??_C@_00CNPNBAHC@?$AA@));
  4. try
  5. {
  6.          basic_string<char,std::char_traits<char>,std::allocator<char> > basic_string<char,std::char_traits<char>,std::allocator<char> >2;
  7.          <Module>.std.basic_string<char,std::char_traits<char>,std::allocator<char> >.{ctor}(ref basic_string<char,std::char_traits<char>,std::allocator<char> >2, (sbyte*)(&<Module>.??_C@_00CNPNBAHC@?$AA@));
  8.          try
  9.          {
  10.                  if (util.convertToUnmanagedString(Name, ref basic_string<char,std::char_traits<char>,std::allocator<char> >))
  11.                  {
  12.                         if (util.convertToUnmanagedString(SN, ref basic_string<char,std::char_traits<char>,std::allocator<char> >2))
  13.                         {
  14.                               sbyte* ptr = (16 <= *(ref basic_string<char,std::char_traits<char>,std::allocator<char> >2 + 20)) ? basic_string<char,std::char_traits<char>,std::allocator<char> >2 : ref basic_string<char,std::char_traits<char>,std::allocator<char> >2;
  15.                               sbyte** ptr2 = <Module>.GetFeatures((16 <= *(ref basic_string<char,std::char_traits<char>,std::allocator<char> > + 20)) ? basic_string<char,std::char_traits<char>,std::allocator<char> > : ref basic_string<char,std::char_traits<char>,std::allocator<char> >, ptr);
  16.                               if (ptr2 != null)
  17.                               {
  18.                                    int i = 0;
  19.                                    if (0 != *(int*)ptr2)
  20.                                    {
  21.                                        while (< 100)
  22.                                        {
  23.                                           list.Add(new string(*(int*)((IntPtr)(* 4) / sizeof(sbyte*) + ptr2)));
  24.                                           <Module>.free(*(int*)((IntPtr)(* 4) / sizeof(sbyte*) + ptr2));
  25.                                           *(int*)((IntPtr)(* 4) / sizeof(sbyte*) + ptr2) = 0;
  26.                                           i++;
  27.                                           if (0 == *(int*)((IntPtr)(* 4) / sizeof(sbyte*) + ptr2))
  28.                                           {
  29.                                             break;
  30.                                           }
  31.                                        }
  32.                                    }
  33.                                    <Module>.free((void*)ptr2);
  34.                               }
  35.                         }
  36.                  }
  37.          }

в своей функции делаю такой результат (список из одной строки "999" для проверки)
Code:
  1. p:=AllocMem(4);
  2.   p1:=AllocMem(4);
  3.   PDWORD(DWORD(p))^:=dword(p1);
  4.   PByte(DWORD(p1))^:=$39;
  5.   PByte(DWORD(p1)+1)^:=$39;
  6.   PByte(DWORD(p1)+2)^:=$39;
  7.   Result:=dword(p);


краш происходит на <Module>.free , который вызывает msvcr100.free. т.е. идет попытка осовобоить память область памяти где хранятся строки и в конце память где хранятся указатели на эти строки. краш происходит в обоих случаях вызова. исключение вроде такое: попытка чтения или записи в защищенную область памяти
если в отладчке занопить эти два вызова, то все отрабатывается на ура.

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




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

Создано: 08 ноября 2016 00:42
· Личное сообщение · #2

zds

Нужно выделять память через malloc().

-----
vx


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

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

Создано: 08 ноября 2016 01:33
· Личное сообщение · #3

difexacaw
не помогает
пробовал
function malloc(Size: Integer): Pointer; cdecl; external 'msvcr100.dll'
GetMem
SysGetMem




Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 08 ноября 2016 01:44
· Личное сообщение · #4

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

-----
[nice coder and reverser]


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


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

Создано: 08 ноября 2016 02:03
· Личное сообщение · #5

zds

Во free используется освобождение кучи с её описателем, который хранится в той же либе с ртл. Есно если передать туда указатель из другой кучи или вообще не корректное значение, то возникнет ошибка. Возможно есть есчо проблема, с указателем(он может как то дополнительно обрабатываться этим Module.free). Нужно в отладчике смотреть.

-----
vx


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

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

Создано: 08 ноября 2016 02:17 · Поправил: zds
· Личное сообщение · #6

Hellspawn
смотрел оригинальный код - идет выделение памяти через через malloc, потом идет вызов dll лицензирования (dll2), которая возвращает нулевое значение (у меня нет лицензии) и выделенная память очищается через free. это то, что происходит в GetFeatures (вызов которой я прикладывал в первом посте).

сам освободить буффер не могу, повторного обращения нет к этой функции. я в самом начале GetFeatures делаю jump в свою dll где делаю нужный мне ответ
Code:
  1.   
  2.   function malloc(Size: Integer): Pointer; cdecl; external 'msvcr100.dll'
  3.  
  4.   p:=malloc(4);
  5.   p1:=malloc(4);
  6.   PDWORD(DWORD(p))^:=dword(p1);
  7.   PByte(DWORD(p1))^:=$39;
  8.   PByte(DWORD(p1)+1)^:=$39;
  9.   PByte(DWORD(p1)+2)^:=$39;
  10.   PByte(DWORD(p1)+3)^:=$00;
  11.   Result:=dword(p);


да я тоже уже думал занопить, если не получится разобраться

Добавлено спустя 17 минут
difexacaw
да, спасибо. похоже проблема именно в этом. потому что когда я смотрел, что делает free, заметил что она вызывает
BOOL WINAPI HeapFree(
_In_ HANDLE hHeap,
_In_ DWORD dwFlags,
_In_ LPVOID lpMem
);
первый аргумент которой это видимо и есть описатель. но в начале я не придал этому значение, т.к. в сама free принимает один аргумент

походу вариант только один - занопить эти два вызова и не терять времени



Ранг: 315.1 (мудрец), 631thx
Активность: 0.30.33
Статус: Модератор
CrackLab

Создано: 08 ноября 2016 08:08
· Личное сообщение · #7

zdsничего ты не сделаешь, забей.
что в плюсах что в делфи запилины свои мененгеры памяти, и всеми new/delete, getmem/freemem/s:= '123'/ и тд управляет этот класс, и даже если ты извратишься и каким либо образом освободишь обл.памяти через напр. heapfree, то класс об этом ничего знать не будет




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

Создано: 08 ноября 2016 10:21
· Личное сообщение · #8

SReg

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

-----
vx



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


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