coverting physical drive to logical drive how to?

c++ / delphi package - dll injection and api hooking

coverting physical drive to logical drive how to?

Postby bluedragon99 » Wed Aug 30, 2006 10:11 pm

Need to convert \Device\HarddiskVolume1\WINDOWS\system32\calc.exe

to C:\windows\system32\calc.exe


I'm hooking createsection btw


Thanks!
bluedragon99
 
Posts: 87
Joined: Thu Jun 02, 2005 3:46 am

Postby madshi » Thu Aug 31, 2006 7:49 am

madshi
Site Admin
 
Posts: 8026
Joined: Sun Mar 21, 2004 5:25 pm

Postby bluedragon99 » Thu Aug 31, 2006 7:33 pm

Anyone want to take a stab at converting this to a function that you can feed in the symbolic link (device\hardiskvolume) and returns the drive letter + path?? I'm just not that savy in delphi yet. I will keep trying though



Code: Select all
Procedure MapSymbolicLinks(const LV: TListView);
const mem_sz = 16000;
var
     p: PChar;
 sz, i: cardinal;
   buf: array [0..MAX_PATH] of char;
    sl: TStringList;
begin
   sl := TStringList.Create();
   try
    GetMem(p, mem_sz);
    ZeroMemory(@buf, sizeof(buf));
    sz := QueryDosDevice(nil, @p^, mem_sz);
    for i := 1 to sz do
    if p[i] = #0 then
    p[i] := #10;
    sl.CommaText := p;
    lv.Items.BeginUpdate();
   for i := 0 to sl.count-1 do
   begin
   with
    Lv.Items.Add() do
    begin
    Caption := sl[i];
    QueryDosDevice(@PChar(sl[i])^, @buf, sizeof(buf));
      with Subitems do
      Add(buf);
     end;
   end;
   finally
    FreeMem(p);
    sl.Free;
    Lv.Items.EndUpdate();
   end;
end;
bluedragon99
 
Posts: 87
Joined: Thu Jun 02, 2005 3:46 am

Postby iconic » Fri Sep 01, 2006 2:38 pm

The least painful way is the create a second string list object and make it function as a hash table with name = value pairs so that you can just feed in the symbolic name and return the logical name.
Enjoy.

Code: Select all
function LogicFromSymbolic(const SymLink: string): string;
const mem_sz = 16000;
var
     p: PChar;
 sz, i: cardinal;
   buf: array [0..MAX_PATH] of char;
    sl, sl2: TStringList;
begin
    if SymLink = '' then
    Exit;
    Sl := TStringList.Create();
   Sl2 := TStringList.Create();
 try
    GetMem(p, mem_sz);
    ZeroMemory(@buf, sizeof(buf));
    sz := QueryDosDevice(nil, @p^, mem_sz);
    for i := 1 to sz do
    if (p[i] = #0) then
    p[i] := #10;
    Sl.CommaText := p;
   for i := 0 to Sl.Count-1 do
   begin
    QueryDosDevice(@PChar(Sl[i])^, @buf, sizeof(buf));
    Sl2.values[buf]:= Sl[i];
   end;
   if (SymLink[1] <> '\') then
     result := Sl2.Values['\' + SymLink]
    else
     result := Sl2.Values[SymLink]
 finally
    FreeMem(p);
    Sl.Free;
    Sl2.Free;
   end;
end;


--Iconic
iconic
 
Posts: 674
Joined: Wed Jun 08, 2005 5:08 am

Postby iconic » Fri Sep 01, 2006 2:44 pm

The least painful way is the create a second string list object and make it function as a hash table with name = value pairs so that you can just feed in the symbolic name and return the logical name.
Enjoy.

Code: Select all
function LogicFromSymbolic(const SymLink: string): string;
const mem_sz = 16000;
var
     p: PChar;
 sz, i: cardinal;
   buf: array [0..MAX_PATH] of char;
    sl, sl2: TStringList;
begin
    result := '';
    if SymLink = '' then
    Exit;
    Sl := TStringList.Create();
   Sl2 := TStringList.Create();
 try
    GetMem(p, mem_sz);
    ZeroMemory(@buf, sizeof(buf));
    sz := QueryDosDevice(nil, @p^, mem_sz);
    for i := 1 to sz do
    if (p[i] = #0) then
    p[i] := #10;
    Sl.CommaText := p;
   for i := 0 to Sl.Count-1 do
   begin
    QueryDosDevice(@PChar(Sl[i])^, @buf, sizeof(buf));
    Sl2.values[buf]:= Sl[i];
   end;
   if (SymLink[1] <> '\') then
     result := Sl2.Values['\' + SymLink]
    else
     result := Sl2.Values[SymLink]
 finally
    FreeMem(p);
    Sl.Free;
    Sl2.Free;
   end;
end;



If you're a performance freak then after the call to QueryDosDevice() in the last "for" loop, check to see if buf = symlink, set the result to sl[i] and Break the loop, that way the entire list doesn't need to be filled.

--Iconic
iconic
 
Posts: 674
Joined: Wed Jun 08, 2005 5:08 am

Postby bluedragon99 » Fri Sep 01, 2006 11:30 pm

thanks iconic you rock
bluedragon99
 
Posts: 87
Joined: Thu Jun 02, 2005 3:46 am

Postby iconic » Sat Sep 02, 2006 8:32 am

no problem :D

I hooked NtCreateSection() last month, or maybe it was in late Jul. can't remember. I have posted some test code on the forum that u can look at it if u so desire.

Also, that hash table idea is handy for mapping between logical and symbolic link names and I usually create a shared memory section that holds the table mappings so that I can look them up easily and save my program from allocating a 16k buffer and looping twice everytime I want to look up a name equivalent. If you end up just calling the function multiple times and you want "real time" results I'd suggest you break the loop and disregard the hash table idea, on my machine it takes approx. 33 ms. to complete, depending on which symbolic name I feed in, which might be the last name gathered when the loop finishes and the list fills. breaking the loop with the equivalent name takes 0 - 5 ms for me. So if you're calling it repeatedly I'd suggest breaking the loop and not using the table. I use a table to avoid many function calls, function calls = cpu time and in NtCreateSection that could be a lot of calls.

optimized for you, since you're new to Delphi.

Code: Select all
function LogicFromSymbolic(const SymLink: string): string;
const mem_sz = 16000;
var
     p: PChar;
 sz, i: cardinal;
   buf: array [0..MAX_PATH] of char;
    sl: TStringList;
begin
    result := '';
    if SymLink = '' then
    Exit;
    Sl := TStringList.Create();
 try
    GetMem(p, mem_sz);
    ZeroMemory(@buf, sizeof(buf));
    sz := QueryDosDevice(nil, @p^, mem_sz);
    for i := 1 to sz do
    if (p[i] = #0) then
    p[i] := #10;
    Sl.CommaText := p;
   for i := 0 to Sl.Count-1 do
   begin
    QueryDosDevice(@PChar(Sl[i])^, @buf, sizeof(buf));
      if (lstrcmpi(@PChar(SymLink)^, @buf) = 0) then
    begin
     result := Sl[i];
     Break;
    end;
   end;
 finally
    FreeMem(p);
    Sl.Free();
   end;
end;


--Iconic
iconic
 
Posts: 674
Joined: Wed Jun 08, 2005 5:08 am

Postby uall » Sat Sep 02, 2006 11:17 am

Why are you writing: @PChar(Sl[i])^ ?
Its the same as PChar(Sl[i])...

Code: Select all
function LogicFromSymbolic(const SymLink: string): string;
  function GetMemNeeded: Integer;
  var
    dwSize: DWord;
    pTargetString: PChar;
  begin
    dwSize := 1;
    repeat
      pTargetString := StrAlloc(dwSize);
      Result := QueryDosDevice(nil,pTargetString,dwSize);
      StrDispose(pTargetString);
      dwSize := dwSize+dwSize;
    until Result <> 0;
  end;
var
  pTargetString: PChar;
  buf: PChar;
  dwMemNeeded: Integer;
  dwFrom: Integer;
  pDevice: PChar;
  I: Integer;
begin
  Result := '';

  dwMemNeeded := GetMemNeeded;
  pTargetString := StrAlloc(dwMemNeeded);
  buf := StrAlloc(MAX_PATH);

  dwMemNeeded := QueryDosDevice(nil, pTargetString, dwMemNeeded);
  for i := 0 to dwMemNeeded-1 do
  begin
    if pTargetString[i] = '#' then
      pTargetString[i] := #0;
  end;
  dwFrom := 0;
  while (dwFrom < dwMemNeeded) do
  begin
    pDevice := PChar(@pTargetString[dwFrom]);
    QueryDosDevice(pDevice, buf, MAX_PATH);
    if (buf = SymLink) then
      Result := pDevice;
    dwFrom := dwFrom+Length(pDevice)+1;
  end;

  StrDispose(buf);
  StrDispose(pTargetString);
end;

uall
 
Posts: 254
Joined: Sun Feb 20, 2005 1:24 pm

Postby iconic » Sat Sep 02, 2006 2:43 pm

The way I have it is fine, it's identical to a simple PChar typecast as u have shown and the reason I do it is because I have always written it like this so it's habitual. By the way, StrAlloc() is somewhat deprecated so I could also wonder why one would use it here, in your code. It's mainly used for backwards compatibility. There's also more than 1 way to do something.

--Iconic
iconic
 
Posts: 674
Joined: Wed Jun 08, 2005 5:08 am

Result empty

Postby Unlimited » Fri Mar 02, 2007 3:12 am

Why, it's doesn't work for me? The result it's empty. I'm using this code to get the device string:

Code: Select all
function FileNameFromFileHandle(const hF: HFILE): string; stdcall;
 type
  UNICODE_STRING = packed record
           len: Word;
        maxlen: Word;
           buf: PWideChar;
 end;
  OBJECT_NAME_INFORMATION = record
   name: UNICODE_STRING;
 end;
 const
  ONI = 1;
  UNICODE_MAX_PATH = MAX_PATH *sizeof(WCHAR);
 var
                ret: Integer;
             status: Integer;
               pONI: ^OBJECT_NAME_INFORMATION;
      ZwQueryObject: TZwQueryObject;
begin
  result := '';
  @ZwQueryObject := GetProcAddress(GetModuleHandleW('ntdll.dll'), 'ZwQueryObject');
  if @ZwQueryObject = nil then
  Exit;
  GetMem(pONI, UNICODE_MAX_PATH);
  ZeroMemory(pOni, sizeof(OBJECT_NAME_INFORMATION));
  status := ZwQueryObject(hF, ONI, @pONI^, UNICODE_MAX_PATH, ret);
if NT_SUCCESS(status) then
  result := WideToAnsiEx(@pONI^.name.buf^);
  FreeMem(pONI);
end;


And this:
Code: Select all
function LogicFromSymbolic(const SymLink: string): string;
const
  mem_sz = 16000;
var
  p: PChar;
  sz, i: cardinal;
  buf: array [0..MAX_PATH] of char;
  sl: TStringList;
begin
  result := '';
  if SymLink = '' then Exit;
  Sl := TStringList.Create();
  try
    GetMem(p, mem_sz);
    ZeroMemory(@buf, sizeof(buf));
    sz := QueryDosDevice(nil, @p^, mem_sz);
    for i := 1 to sz do
    if (p[i] = #0) then
    p[i] := #10;
    Sl.CommaText := p;
    MsgOk(IntToStr(SL.Count));
    for i := 0 to Sl.Count-1 do
    begin
      QueryDosDevice(@PChar(Sl[i])^, @buf, sizeof(buf));
      if (lstrcmpi(@PChar(SymLink)^, @buf) = 0) then
      begin
        result := Sl[i];
        Break;
      end;
    end;
  finally
    FreeMem(p);
    Sl.Free();
  end;
end;


Anyone can help me, please? :cry:
Unlimited
 
Posts: 28
Joined: Wed Feb 14, 2007 4:18 am


Return to madCodeHook

Who is online

Users browsing this forum: Exabot [Bot] and 0 guests

cron