Nie mogę eksportować procedury z pliku .dll

0

Witam.

Posiadam plik dynamic library. Oto jego zawartość:

library hook;

uses
  SysUtils,
  Classes,
  Messages,
  Windows;

{$R *.res}

const
  Adr = $004073F0;

procedure FSpeech (AType: Byte; AText:PChar); cdecl;
var
  FSpeech: procedure(AType: Byte; AText:PChar); cdecl;

begin
  @FSpeech := Ptr(Adr);
  FSpeech(1, 'hello');
end;

exports
FSpeech;
end.

Co zrobiłem nie tak, skoro nie mogę w stworzonym przeze mnie (dzięki tutorialowi z tego forum) pliku exe importować procedury FSpeech?

Proszę o pomoc i dziękuję.

0

Pokaż, jak ją importujesz + co to znaczy "nie mogę"?

0

A co ten kod w ogóle robi? Ustawiłeś sobie jakiś adres na sztywno, pod którym nie wiadomo co będzie i masz nadzieje, że co? że będzie tam jakaś procedura? raczej nie.

//edycja: ciekawe, która procedura zostanie wywołana bo obie mają tą samą nazwę
//edycja 2: jednak zagnieżdżona - tego się nie spodziewałem

0

Eh. Ogólnie to wydaje mi się, że DLL zrobiłem dobrą. Nie musisz na mnie najeżdżać, że wklikałem tam jakiś adres, który nie wiem co robi i w ogóle wyrósł z ziemi. Tak się składa, że w połączeniu z moim exe jednak coś to robi. Chcę tylko, by funkcja była wywoływana po naciśnięciu buttonu. Wiem, że funkcja działa itp, bo przy małych poprawkach i zinjectowaniu działała, jednak tylko raz. Chcę by była wykorzystywana (na początek) wtedy, kiedy nacisnę na buttona. Do tego jednak muszę ogarnąć właśnie tą .dll tak, by ten export był możliwy.

W exeku natomiast wygląda to tak:

var
  DLL : THandle; // uchwyt biblioteki
  FSpeech : procedure;
begin
  DLL := LoadLibrary('hook.dll'); // laduj biblioteke
  try
    @FSpeech := GetProcAddress(DLL, 'FSpeech'); // laduj procedure
    if @FSpeech=nil then raise Exception.Create('Bład - nie mogę znaleźć proceudry w bibliotece!');
    FSpeech; // wywolaj procedure
  finally
    FreeLibrary(DLL); // wreszcie zwolnij pamiec
  end;
end; 

Jeżeli ktoś łapie co jest nie tak to proszę o pomoc. Dziękuję.

@edit.
Problem polega na tym, że pojawią się "Bład - nie mogę znaleźć proceudry w bibliotece!" komunikat.

0

W exeku masz zupełnie inną deklarację procedury FSpeech, niż w bibliotece - brak parametrów, brak określonej konwencji wywołania parametrów; Pozmieniaj to, żeby było dokładnie tak samo w obu miejscach;


Przykład procedury w DLL:

  procedure FSpeech(AType: Byte; AText: PChar); cdecl;
  begin
    // code here
  end;

exports
  FSpeech;

begin
end.

i ładowania jej w aplikacji (tu: konsolowej):

var
  hLib: THandle;
  FSpeech: procedure(AType: Byte; AText: PChar); cdecl;
begin
  hLib := LoadLibrary(PChar(ExtractFilePath(ParamStr(0)) + 'libfoo.dll'));
  try
    @FSpeech := GetProcAddress(hLib, 'FSpeech');

    if @FSpeech = nil then
      Write('Cannot load the FSpeech procedure!')
    else
      Write('FSpeech successfully loaded!');
  finally
    FreeLibrary(hLib);
    ReadLn;
  end;
end.

Na ekranie wyświetla się komunikat FSpeech successfully loaded!, więc gra gitara; Projekt w załączniku, bez pliku wykonywalnego.

0

Okej, dzięki ;)
Mam jednak kolejny problem. Dll w takiej postaci mi działa:

 library say;

uses
  SysUtils,
  Classes,
  Messages,
  Windows;

{$R *.res}

const
  AdrSay = $004073F0;

var
  JustSay: procedure(AType: Byte; AText:PChar); cdecl;

begin
  @JustSay := Ptr(AdrSay);
  JustSay(1, 'hello');
end.

Gdy chcę jej użyć wystarczy użyć injectora i to działa. Jednak jak widać na początku tematu próbowałem to zmienić tak, by tą funkcję użyć za każdym razem kiedy nacisnę na button. Niestety mam z tym cholerny problem.

Do swojego exe dodałem takie rzeczy:

procedure FSpeech(AType: Byte; AText:PChar); cdecl; stdcall; external 'oskar.dll';

próbowałem je wywoływać:
FSpeech(1, 'hello');, jednak bez skutku. Kompletnie nie mogę tego ogarnąć. Ciągle był jakiś error.

0

Może:

exports FSpeech name 'FSpeech';
0

Rozdziel problem na DWA mniejsze problemy:

• eksportowanie i zaimportowanie zwykłej funkcji (bez kombinowania z adresami), i dopiero potem
• zakombinuj z podmianą adresu

w ten sposób będziesz wiedział, w którym miejscu się zatrzymujesz...

0

Eeee że o co chodzi z tym "sztywnym" adresem i jak to ma niby działać? Wywołujesz coś dziwnego Bóg wie gdzie w programie mieszając potem się dziwisz że program "głupieje" i możesz to wywołać tylko raz? Ja wiem że wstrzykujesz tą DLLkę to jakiegoś procesu ale na moje oko to jak wywołujesz funkcję z DLL to ładujesz ją do twojego procesu i to w w twoim procesie funkcje będzie szukała tego adresu. Zresztą od czego są debuggery sprawdź co naprawdę sie dzieje a nie tak "po omacku".

0

Jest to adres z olydbg. Niestety nie ogarniam debuggera na tyle, by ogarnąć co jest nie tak :D

Nie wiem no. Na moje oko wygląda to dobrze.
Proszę. Oto exe:

 unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  PH: THandle;
  PID, ThID: DWORD;
  H: THandle;

implementation
procedure FSpeech(AType: Byte; AText:PChar); cdecl; external 'oskar.dll';
{$R *.dfm}

procedure Hook;
begin
  H := FindWindow('', nil);
  if (H <> 0) then
    begin
      ThID := GetWindowThreadProcessId(H, @PID);
      PH := OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
      FlashWindow(H, true)
    end
  else
    begin
      ShowMessage('Open your ...!');
      Application.Terminate;
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
hook;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
fspeech(1,'lol');
end;

end.

A to .dll:

 library oskar;

uses
  SysUtils,
  Classes,
  Messages,
  Windows;

{$R *.res}

procedure FSpeech(AType: Byte; AText:PChar); cdecl; export;

const
  Adr = $004073F0;

var
  FSpeech: procedure(AType: Byte; AText:PChar);

begin
  @FSpeech := Ptr(Adr);

end;

exports
FSpeech;
end.

Jakby ktoś wpadł na to co jest nie tak to niech pomoże. Ja nadal będę kombinować. Jak mi coś wyjdzie to dam znać xd

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0