Доброго всем дня! Помогите пожалуйста восстановить с++ код функции, дизассемблированной с помощью ida pro. В реальной жизни функция валится на строчке Код (Text): 7333F15A movsx eax, byte ptr [edx] и я хотел бы узнать почему. Я так понимаю, что в функции задействованы строки. Код (Text): 7333F130 ; int __stdcall ChangeName(int,int) 7333F130 _ChangeName@8 proc near ; CODE XREF: PrintMessage(x,x,x)+2A0p 7333F130 7333F130 var_C = dword ptr -0Ch 7333F130 var_8 = dword ptr -8 7333F130 var_4 = dword ptr -4 7333F130 arg_0 = dword ptr 8 7333F130 arg_4 = dword ptr 0Ch 7333F130 7333F130 push ebp 7333F131 mov ebp, esp 7333F133 sub esp, 0Ch 7333F136 push edi 7333F137 mov [ebp+var_8], 0 7333F13E mov edi, [ebp+arg_4] 7333F141 or ecx, 0FFFFFFFFh 7333F144 xor eax, eax 7333F146 repne scasb 7333F148 not ecx 7333F14A add ecx, 0FFFFFFFFh 7333F14D mov eax, [ebp+arg_4] 7333F150 lea ecx, [eax+ecx-1] 7333F154 mov [ebp+var_4], ecx 7333F157 7333F157 loc_7333F157: ; CODE XREF: ChangeName(x,x)+3Bj 7333F157 mov edx, [ebp+var_4] 7333F15A movsx eax, byte ptr [edx] 7333F15D cmp eax, 27h 7333F160 jz short loc_7333F16D 7333F162 mov ecx, [ebp+var_4] 7333F165 sub ecx, 1 7333F168 mov [ebp+var_4], ecx 7333F16B jmp short loc_7333F157 7333F16D ; --------------------------------------------------------------------------- 7333F16D 7333F16D loc_7333F16D: ; CODE XREF: ChangeName(x,x)+30j 7333F16D mov edx, [ebp+var_4] 7333F170 sub edx, 1 7333F173 mov [ebp+var_4], edx 7333F176 7333F176 loc_7333F176: ; CODE XREF: ChangeName(x,x)+63j 7333F176 mov eax, [ebp+var_4] 7333F179 movsx ecx, byte ptr [eax] 7333F17C cmp ecx, 27h 7333F17F jz short loc_7333F195 7333F181 mov edx, [ebp+var_4] 7333F184 sub edx, 1 7333F187 mov [ebp+var_4], edx 7333F18A mov eax, [ebp+var_8] 7333F18D add eax, 1 7333F190 mov [ebp+var_8], eax 7333F193 jmp short loc_7333F176 7333F195 ; --------------------------------------------------------------------------- 7333F195 7333F195 loc_7333F195: ; CODE XREF: ChangeName(x,x)+4Fj 7333F195 cmp [ebp+var_8], 1Eh 7333F199 jle short loc_7333F1A4 7333F19B mov [ebp+var_C], 1Eh 7333F1A2 jmp short loc_7333F1AA 7333F1A4 ; --------------------------------------------------------------------------- 7333F1A4 7333F1A4 loc_7333F1A4: ; CODE XREF: ChangeName(x,x)+69j 7333F1A4 mov ecx, [ebp+var_8] 7333F1A7 mov [ebp+var_C], ecx 7333F1AA 7333F1AA loc_7333F1AA: ; CODE XREF: ChangeName(x,x)+72j 7333F1AA mov edx, [ebp+var_C] 7333F1AD mov [ebp+var_8], edx 7333F1B0 mov eax, [ebp+var_8] 7333F1B3 push eax ; size_t 7333F1B4 mov ecx, [ebp+var_4] 7333F1B7 add ecx, 1 7333F1BA mov [ebp+var_4], ecx 7333F1BD mov edx, [ebp+var_4] 7333F1C0 push edx ; char * 7333F1C1 mov eax, [ebp+arg_0] 7333F1C4 add eax, 11Eh 7333F1C9 push eax ; char * 7333F1CA call ds:__imp__strncpy 7333F1D0 add esp, 0Ch 7333F1D3 mov ecx, [ebp+arg_0] 7333F1D6 add ecx, [ebp+var_8] 7333F1D9 mov byte ptr [ecx+11Eh], 0 7333F1E0 mov edx, [ebp+arg_0] 7333F1E3 mov dword ptr [edx+152h], 1 7333F1ED pop edi 7333F1EE mov esp, ebp 7333F1F0 pop ebp 7333F1F1 retn 8 7333F1F1 _ChangeName@8 endp 7333F1F1 Заранее спасибо.
1. Лучше дай бинарник - понять на глаз, без отладки что именно делает эта функция сложновато. 2. Есть такой плагин для IDA - называется HexRays. Он представляет ассемблерный код в Си-виде.
Приаттачиваю библиотеку: это db-library для доступа к MS SQL. У меня она упорно валится с Access Violation, хочу разобраться что к чему. Попробую запользовать Hex-Rays, спасибо за совет
параметром процедуры передается адрес строки (arg_4). Далее определяется длина строки (признаком конца считается байт 00), и начиная с конца, ищется символ с кодом 27h... Следовательно, валиться на вышеупомянутом месте может в единственном случае: длина строки = 0 (пустая строка) - тогда мы пытаемся что-то искать по адресу, находящемуся ПЕРЕД строкой (в общем случае неизвестно, что там такое, и имеем ли мы право вообще что-то там читать) пардон, не в единственном - еще есть случай, когда в строке нет байта 27h )) тогда даже при правильном определении длины, мы рано или поздно покинем пределы строки и пойдем в младшие адреса, где случится тоже самое, что и в первом случае Код (Text): ;InStrPos = Arg_4+Len(Arg_4_String)-1 ;А способ определения длины строки таков, что (если меня не переглючило), ; при строке длины 0 мы получим длину 0... А адрес Arg_4-1 - это уже не строка, ; а какая-то другая переменная... возможно, находящаяся в области памяти, ; куда мы читать/писать не можем 7333F157 @Loop: mov edx, [InStrPos] 7333F15A movsx eax, byte ptr [edx] 7333F15D cmp eax, 27h 7333F160 jz @Next 7333F162 mov ecx, [InStrPos] 7333F165 sub ecx, 1 7333F168 mov [InStrPos], ecx 7333F16B jmp @Loop @Next: В этом коде нигде нет проверки на текущее положение указателя в строке. То есть, если байт 27h не найден, то мы пройдем всю строку и начнем подниматься в младшие адреса, пока не получим исключение. ACCESS VIOLATION )))) а код писал индус. И случая пустой строки, или строки, не имеющей кавычки ('), не предусмотрел ...более того, дальше идет поиск второй кавычки... также без проверки, не вышли ли за пределы строки... То есть если в передаваемой строке кавычка есть, но только 1... то вылетит с тем же ACCESS VIOLATION по адресу 7333F179
Так и есть. При коннекте к английскому sql серверу, в строке действительно присутствует символ ' - 0x27. При коннекте к русскому sql серверу в строке вместо ' присутствует " и все падает. Может знатоки знают, как можно технично поменять проверку с 0x27 на 0x22 ?
Патч 2 байта в длл ) меняй cmp eax, 27h на cmp eax, 22h в обоих местах Но это все равно жуткий косяк А кто автор кода? Неужели Майкрософт??? Сам посмотреть не могу - "архив поврежден или имеет неизвестный формат"
Ага, Microsoft. Два дня уже мучаюсь. Сегодня догадался как отладить кусок, плюс вы еще все подсказали куда двигаться. Буду сейчас думать что делать, то ли патч писать, то ли фиг знает. Вообще хотелось чтобы работало безо всяких патчей, но чувствую что это у меня вряд ли получится. А вообще проблема решается установкой у русского sql сервера языком по умолчанию - english.
Рекомендую пропатчить вот так: ... cmp eax, 27h je addr1 cmp eax, 22h je addr1 dec byte ptr [ebp-8] nop ... cmp ecx, 27h je addr2 cmp ecx, 22h je addr2 dec byte ptr [ebp-8] nop ... Правильно обработаются и апострофы, и кавычки.
samodelkin А где-нить в настройках (сервера, драйверов) нет возможности задать ограничитель значений текстовых полей?