• XSS.stack #1 – первый литературный журнал от юзеров форума

DELPHI и API(возврат API в EAX)

/dev/AVR

RAID-массив
Пользователь
Регистрация
11.11.2005
Сообщения
86
Реакции
0
Код:
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils,WIndows;
  var WinDir:pchar;
  res:cardinal;
  begin

GetWindowsDirectory(WinDir,MAX_PATH);
writeln('aaa');

end.

При таком исполнении дельфяка завершает исполнение программы после APIшки.

Код:
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils,WIndows;
  var WinDir:pchar;
  res:cardinal;
  begin

res:=GetWindowsDirectory(WinDir,MAX_PATH);
writeln('aaa');

end.

При таком исполнении прога работает как надо(доходит до конца).
Т.е я должен всегда принимать возвратное значение каждой APIшки.
Однако в данном случае RES=EAX и API функция по любому возвращает резалт своей работы.
(в независимости от того поставил я RES:= или нет, результат будет в EAX).
Вроде бы в обоих случаях нарушений нет(с точки зрения API), однако почему тогда прога раньше завершает работу
Что тут не так ?
 
Код:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;
var
  WinDir:pchar;
  res:cardinal;
begin
  { TODO -oUser -cConsole Main : Insert code here }
  GetWindowsDirectory(@WinDir,MAX_PATH);
  writeln('aaa');
end.
 
Так PCHAR это и есть указатель, а собачка- адрес указателя.
Pointer to the buffer Так требует MSDN. Почему указатель напрямую не идет ?

Проблема то не смертельная, просто интересно.
 
МДа, EAX=0
Код:
00408174   . 68 04010000    PUSH 104          ; /BufSize = 104 (260.)
00408179   . 50             PUSH EAX  ; |Buffer 
0040817A   . E8 45C8FFFF    CALL <JMP.&kernel32.GetWindowsDirectoryA>; GetWindowsDirectoryA

Код:
00408174   . 68 04010000    PUSH 104                                ; /BufSize = 104 (260.)
00408179   . 68 98A74000    PUSH Project2.0040A798  ; |Buffer = Project2.0040A798
0040817E   . E8 41C8FFFF    CALL <JMP.&kernel32.GetWindowsDirectoryA>; GetWindowsDirectoryA

В дизасме то понятно что происходит(указателя на буфер в 1м случае нет :bang: )
Во втором есть , но вот дельфяка похоже сволоч :cry2:
 
Заранее извиняюсь что без дизасма(спать хочу)

Кажется язык высокого уровня не идеален на мой взгляд.
Парсинг DELPHяцого кода в PE файл не всегда правильный.
Особенно в предыдущих случаях. Тут нашел метод борьбы с этим.
По крайней мере- мое мнение на этот счет.

В ASMе то все понятно как происходит, но вот дельфяка при переводе
в ASM не всегда делает все безошибочно на примере тех APIшек.
С таким столкнулся я только при юзанье APIшек у которых в MSDNе
строго прописанно BUFFER. Там где string PCHAR подходит со своим указателем,
А ТАМ где BUFFER уже нет.

Код:
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

var x:pchar;
begin
getWindowsDirectory(x,Max_Path);
writeln(paramstr(0));
writeln(x);
en

Код:
getWindowsDirectory(@x,Max_Path);
writeln(paramstr(0));
writeln(x);

Работает одно из двух в обоих случаях. ЧТо бы работало все и
вроде бы как безошибочно- используем в качестве буфера massiv:array[0..255] of char;

Код:
var x:array[0..255] of char;
begin
getWindowsDirectory(x,Max_Path);
writeln(paramstr(0));
writeln(x);
end.

Вот так вот все ок в обоих случаях. Проделал данную операцию с многими буферными APIшками.
Тогда OK. Если APIшка требует String, значит PCHAR сгодится.

Если я где то ошибаюсь, поправьте пожалуйста.

PS: Мда, ASM конечно хорошая штука, вот только нервные клетки к сожалению не восстанавливаются.
 
/dev/AVR
кстати под LPxxSTR в винде понимается адрес массива символов (указатель то бишь), а не адрес указателя.
Кажется язык высокого уровня не идеален на мой взгляд.
Парсинг DELPHяцого кода в PE файл не всегда правильный.
юзай Си++, винда на нем написана, и будет тебе счастье ;) Там разногласий нет.
Код:
char *buffer = new char[1024];
&buffer - это адрес указателя (т.к. в buffer хранится указатель на массив),
buffer - это значение указателя на указатель, то есть адрес начала массива.
 
Ладно, черт с ним. Нашел выход из ситуации- це ж и добра.
LPxxSTR-адрес массива символов. В принципе строка это тоже массив символов.
Ну и черт этой дельфяке дать. В дизасме с buff:array все выглядит нормально.

А что @buff будет выглядеть так PUSH Project1.xxxxxx
Или buff вот так MOV EAX,DWORD PTR DS:[xxxxxx];
CALL <Project1.@@LStrToPChar>
PUSH EAX
PUSH 0
CALL <JMP.&user32.MessageBoxA>

Как то без разницы. Главное что работает.

TO MODERATORS&Administrators тему можно закрывать т.к
с ASMеной части понятно что происходит, да и с дельфяцкой тоже найдено
"что делать" :baby:
 
Что за бред вообще?:) Тут вопрос лишь в ограниченности знаний и не более, называть Delphi ущербным языком просто уму непостижимо, достаточно просто взять книжку по Delphi и прочитать главу: Типы данных, приведение типов, работа с разынми типами данных.
 
TO BUGOR я не считаю DELPHI ущербным, просто
это единственный случай(буффер), на который я нарвался и с ASM точки зрения
более понятно чем с DELPHяцкой было.
На DELPHI пишу 2 года и каких либо недоработок я не видал кроме этой...

Может быть действительно ограничение знаний...
PS: А дефекты могут быть везде. Даже в AVR STUDIO есть(вроде бы фирменный ASM под AVR, а в отладчике на 4 retАХ начинаются ошибки проги)...
Дефект или не дефект... Покажите мне статью где бы писалось что так делать нельзя :)

MODERATORS&ADMINS закрывайте топик, а то сейчас начнется полный оффтоп
класса "Дельфа это идеальный продукт без ошибок, /dev/AVR лол и т.д."
 
Слава богу. Для меня вот так вот будет намного понятнее работа с буфером
Код:
procedure TForm1.FormCreate(Sender: TObject);
var x:pointer;
begin

getmem(x,100);

GetWindowsDirectory(x,100);

Messagebox(application.handle,x,x,80);
freemem(x,100);
showmessage(paramstr(0));

end;
 
BUG(O)R, с чего вдрук? %)

ну скомпиль код

program Project1;
{$APPTYPE CONSOLE}

uses
Windows;

var
WinDir: pchar;

begin
GetWindowsDirectory(@WinDir,MAX_PATH);
writeln(windir);
readln;
end.


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

Код:
program Project1;
{$APPTYPE CONSOLE}

uses
Windows;

var
WinDir: pchar;

begin
GetWindowsDirectory(@WinDir,MAX_PATH);
writeln(pChar(@windir));
readln;
end.
 
да хз я чето %)

program mem;

uses
Windows;

var
p: Pointer;
p2: Pointer;

begin
//
GetTempPath(255, @p);
GetWindowsDirectory(@p2, 255);
//
messagebox(0, PChar(@p), PChar(@p2), 0);
end.


раз такая пьянка, то где то тут автовыделение памяти? %))
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх