Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Find what app loaded my dll.

Posted on 2004-09-29
13
Medium Priority
?
407 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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
 

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 500 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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Suggested Courses

610 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