Solved

Find what app loaded my dll.

Posted on 2004-09-29
13
399 Views
Last Modified: 2010-04-05
I have found a DLL on my computer that is obviously a virus, but it is not detected by any AV's. My guess is its one of the kids i go to school with trying to take down my box. (which we do to each other for fun.)

Any who, im creating my own DLL and renaming it to the DLL i found. In my DLL i would like it to let me know which app started it so i can remove the DLL loader. Any suggestions?
0
Comment
Question by:jentil
  • 5
  • 4
  • 3
  • +1
13 Comments
 
LVL 6

Expert Comment

by:gwalkeriq
ID: 12185713
As a simple suggestion, goto sysinternals.com and download process explorer (it's free)

http://www.sysinternals.com/ntw2k/freeware/procexp.shtml

Once you run ProcExp.exe, it shows all running processes, there is a menu option, View, Lower Pane View, DLL's, once you do that, you see all of the DLL's used by each process.

I could tell you how to write what you ask, but then I would have to kill you. Actuallly, I don't know how to get what you ask without doing a lot of work, though I am not certain I know everything that would be necessary. GetCurrentProcessID is the API call that gets you to the process, but there is not much you can easily do with that to figure out the process details. If the process has a window handle, you could enumerate through the windows looking for the matching process. But if you just want to solve your problem, try process explorer
0
 
LVL 6

Expert Comment

by:gwalkeriq
ID: 12185728
Just occured to me after submitting, that you could call GetCommandLine, not sure whether this work correctly in a DLL, but would be easy to try.
0
 
LVL 6

Expert Comment

by:gwalkeriq
ID: 12185750
Sorry, rambling on but ...
You should go to sysinternals anyway if you've not been there, they have lots of good stuff. I had forgotten about a couple of their utils, i.e., ListtDLLs and AutoRuns are quite pertinent to your problem. Others are quite nice too if you have interest win how Windows works.
0
 

Author Comment

by:jentil
ID: 12186620
I have used the tools you suggested, but the process explorer only shows which process is currently using the DLL, which is explorer and taskmanager. It doesnt say how the DLL got loaded in the first place. Ill keep looking. I really would like to just be able to code a program that monitors the dll and says which app is trying to access it.
0
 
LVL 2

Expert Comment

by:php4delphi
ID: 12188223
You can try to do it using Jedi Code Library (JCL)

unit Unit1;

interface

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

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

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses
  jclSysInfo;

procedure TForm1.Button1Click(Sender: TObject);
var
  ProcessList : TStringList;
  DLLList : TStringList;
  cnt : integer;
  MyDLLName : string;
begin
  MyDLLName := 'c:\windows\test.dll';
  ProcessList := TStringList.Create;
  RunningProcessesList(ProcessList);
  DLLList := TStringList.Create;
  for cnt := 0 to ProcessList.Count - 1 do
   begin
     DLLList.Clear;
     LoadedModulesList(DLLList, cardinal(ProcessList.Objects[cnt]));
     if DLLList.IndexOf(MyDLLName) > -1 then
      ShowMessage(ProcessList[cnt]);
   end;
  DLLList.Free;
  ProcessList.Free;
end;

end.


Or another solution, using DLL:


library lib1;

uses
  Messages,
  Windows;

function GetDllList(AData: PChar):Longint;
var
  mbi : TMemoryBasicInformation;
  nlen1, nlen2 : Integer;
  presult : PChar;
  lp : PByte;
begin
  presult := AData;
  lp := nil;
  while (VirtualQuery(lp, mbi,SizeOf(mbi))=SizeOf(mbi)) do
    begin
      if mbi.State = MEM_FREE then
        mbi.AllocationBase := mbi.BaseAddress;

      if (mbi.AllocationBase = mbi.BaseAddress) and
         (mbi.AllocationBase <> nil) and
         (Dword(mbi.AllocationBase) <> Hinstance) then
        begin
          nlen1 := Wvsprintf(presult, '%08.8X ', @mbi.AllocationBase);
          inc(pResult, nlen1);
          nlen2 := GetModuleFileName(THandle(mbi.AllocationBase), pResult, MAX_PATH);
          if nlen2 > 0 then
            begin
               inc(pResult,nlen2);
               pResult^ := #13;
               inc(presult);
               presult^:= #10;
               inc(pResult);
            end
          else
            dec(pResult, nlen1);
        end;
      inc(lp, mbi.RegionSize);
    end;
    presult^ := #0;
    Result := pResult - AData + 1;
end;

function Answer( nCode: Integer; wprm: WParam; lprm:WParam):LResult;
         stdcall;
type
  PMsg = ^TMsg;
var
  cd : TCopyDataStruct;
  msg : PMsg;
  Caller : HWND;
  AHook: HHook;
  pBuffer: PChar;
begin
  Result := 0;
  msg := PMsg(lprm);

  if (msg.Message = 0) and (msg.LParam <> 0) then
    begin
      AHook := msg.lParam;
      Caller := msg.wParam;
      GetMem(pBuffer, $FFFFF);
      cd.cbData := GetDllList(pBuffer);
      cd.lpData := pBuffer;
      cd.dwData := GetCurrentThreadID;
      SendMessage(Caller, WM_COPYDATA, 0, LParam(@cd));
      FreeMem(pBuffer);
      UnHookWindowsHookEx(AHook);
      PostThreadMessage(GetCurrentThreadID, 0, 0, 0);
    end;
end;

procedure QryDllList(tid: DWord; Caller: HWND);
var
   AHook : Hhook;
begin
   AHook := SetWindowsHookEx(WH_GETMESSAGE, Answer, Hinstance, tID);
   if AHook <> 0 then
     PostThreadMessage(tid, 0, Caller, AHook);
end;

exports
  QryDllList;

begin

end.
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12188449
To get the name of the executable that loaded your DLL, just use ParamStr(0)... For the full commandline, use the CmdLine function. To get the name of your DLL, you'll need to use the GetModuleFileName function. But hey, all you need is the CmdLine...
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

Author Comment

by:jentil
ID: 12189024
But wont i need to know what the DLL exports so that i can export the same name of the function in my DLL?
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12190212
Actually, no. Not if you build your DLL to display you the caller application immediately after it is loaded. This is because every application first has to LOAD your DLL, which will trigger your DLL to execute some initialization code. Once loaded, the application can try to find the methods it needs to call but since it can't find them, it will probably crash...

This DLL would work just fine:

library WhateverItIsCalled;
uses Windows;
begin
  MessageBox( GetDesktopWindow, PChar( cmdLine ), 'Caller', MB_OK );
end.

Compile this project, save the DLL in the right place and you'll get to see the commandline that initiated the load of your DLL. Real rocket-science. :-)
0
 
LVL 6

Expert Comment

by:gwalkeriq
ID: 12190435
jentl -- you can use TDUMP -ee blah.dll to see a list of the exports from the original dll. TDUMP comes with Delphi and has lots of other options. You can also download "Dependency Walker" which is also useful to see all info about programs and dll's. EntryPoint names are often suggestive, but DllMain or names including Init are especially good, DllRegisterServer sounds good, but it is frequently not called by the parent process. Once you make a DLL that can get attached, call GetCommandLine or maybe ParamStr(0) and then log the info to a file since you don't know when the DLL is loaded and you may not have a desktop available for a call to MessageBox.

WorkShop_Alex -- Do you know if ParamStr(0) works when the parent program is not Delphi based? You're right, I completely forgot about GetModuleFileName -- don't recall having ever used it.

0
 
LVL 6

Expert Comment

by:gwalkeriq
ID: 12190530
BTW, if explorer & TaskManager are the processes loading the DLL (as seen in process viewer), I think you will find that these programs are the ones loading the DLL too. ProcessViewer shows a process tree, and as far as I know, you can't load attach a dll for another process unless you are the debugger of that process, I think a debugger should be the parent of the process.
0
 
LVL 17

Accepted Solution

by:
Wim ten Brink earned 125 total points
ID: 12191959
AFAIK, ParamStr(0) should just work with every executable since every executable has a commandline. However, according to the Delphi helpfiles, CmdLine would be nil in DLL's but for some reason I discovered this isn't true. But CmdLine is initialized through the API function GetCommandLine. And this API call seems to return the correct value. I've checked on MSDN. So, technically it should wirk no matter which language was used for the executable.

ParamStr(0) uses the commandline to extract the parameters. But then again, you could also use:

var Buffer: array[0..260] of Char;
begin
  ExeName := GetModuleFileName(0, Buffer, SizeOf(Buffer));

To retrieve just the executable name. But I think it's also interesting to know the parameters that have been used during start-up.
0
 

Author Comment

by:jentil
ID: 12196125
The simplest answer was the correct one, My homemade DLL now tells me every app that trys to launce it, Ill give you a big pat on the back if you can tell me why explorer and outlooke are trying to open the DLL and where the settings are.
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12198255
Since you know the name of the DLL, you could start RegEdit to edit your registry and search for the dll name in the registry. It would not suprise me if you find it there a couple of time... That DLL has probably registered itself as a special module for Explorer and Outlook, thus they keep loading it. But the registration is done throught the registry, so you could find it there.

If it's a COM object though, then you probaly see a socalled GUID near the name of the DLL in the registry. (Something like "{C523F39F-9C83-11D3-9094-00104BD0D535}") It's a good idea to check for that GUID too, if you find it. But just deleting the DLL name from the registry should be enough.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now