2017-02-09 14 views
-2

Ну, basead в мой последний вопрос:Native API: RtlInitUnicodeString перенастройки странные символы

How build a path to file using Native Api and open with NtOpenFile api?

как @Remy Лебо предложил RtlInitUnicodeString() работает очень хорошо, когда SourceString имеет тип:

'\??\c:\test.txt'.

Уже в этом случае здесь после RtlInitUnicodeString() значения в буфера всегда:

'dfᄸɟ\Device\HarddiskVolume2\Windows\SysWOW64\gdi32.dll' см:

enter image description here

со странными символами на старте. И таким образом ясно, что NtOpenFile() не удастся.

Кто-то знает что-то, чтобы решить эту проблему, пожалуйста?

Вот моя последняя попытка:

uses 
    Winapi.Windows, 
    System.SysUtils, 
    System.Classes, 
    NtDll, 
    ntdll_; 

var 
hmod: HMODULE = 0 

type 

    { .: MEMORY_INFORMATION_CLASS :. } 

    _MEMORY_INFORMATION_CLASS = (MemoryBasicInformation, MemoryWorkingSetList, 
    MemoryMappedFilenameInformation, MemorySectionName, 
    MemoryBasicVlmInformation); 
    MEMORY_INFORMATION_CLASS = _MEMORY_INFORMATION_CLASS; 
    TMemoryInformationClass = MEMORY_INFORMATION_CLASS; 
    PMemoryInformationClass = ^TMemoryInformationClass; 

    { .: UNICODE STRING:. } 

    PUnicodeString = ^TUnicodeString; 

    TUnicodeString = packed record 
    Length: Word; 
    MaximumLength: Word; 
    Buffer: PWideChar; 
    end; 

/////////////////////////////////////////////////////////////////////////////// 

procedure UnhookPfn(pfn: Pointer); 
const 
OBJ_CASE_INSENSITIVE = $00000040; 
NtCurrentProcess = THandle(-1); 
var 
pinth: PImageNtHeaders32; 
StrUnicode : TNtUnicodeString 
Name: PUnicodeString; 
oa: TNtObjectAttributes; 
rcb: SIZE_T; 

begin 

if ((RtlPcToFileHeader(pfn, @hmod)) <> (NtNotImplementedPointer)) then 
    begin 

    pinth := RtlImageNtHeader(hmod); 

    GetMem(Name, SizeOf(Name)); 

    FillChar(Name^,SizeOf(Name),#0); 

    if (0 <= NtQueryVirtualMemory(NtCurrentProcess, Pointer(hmod), 
     Integer(MemoryMappedFilenameInformation), Pointer(Name), MAX_PATH * SizeOf(WCHAR), 
     @rcb)) then 
    begin 

     RtlInitUnicodeString(@StrUnicode, PWideChar(Name)); 
     InitializeObjectAttributes(@oa, @StrUnicode, OBJ_CASE_INSENSITIVE, 0, nil); 

    end; 
    FreeMem(Name); 
end; 

{ ::: Usage ::: } 

/// ///////////////////////////////////////////////////////////////////////////// 
var 
BitBltAddr: Pointer; 

begin 
    try 
    hmod := GetModuleHandle('Gdi32.dll'); 
    BitBltAddr := GetProcAddress(hmod, 'BitBlt'); 
    UnhookPfn(BitBltAddr); 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 

end. 

NtDll.pas

ntdll_.pas

EDITION 1:(внушение @RbMm)

procedure UnhookPfn(pfn: Pointer); 
const 
    OBJ_CASE_INSENSITIVE = $00000040; 
    NtCurrentProcess = THandle(-1); 
var 
    pinth: PImageNtHeaders32; 
    Name: PUnicodeString; 
    rcb: SIZE_T; 
    iosb: TIoStatusBlock; 
    oa: TNtObjectAttributes; 
    StrPath : TNtUnicodeString; 

begin 

    if ((RtlPcToFileHeader(pfn, @hmod)) <> (NtNotImplementedPointer)) then 
    begin 

    pinth := RtlImageNtHeader(hmod); 

    GetMem(Name, SizeOf(Name)); 

    FillChar(Name^,SizeOf(Name),#0); 

    if (0 <= NtQueryVirtualMemory(NtCurrentProcess, Pointer(hmod), 
     Integer(MemoryMappedFilenameInformation), Pointer(Name), MAX_PATH * SizeOf(WCHAR), // Name buffer = '\Device\HarddiskVolume2\Windows\SysWOW64\gdi32.dll' 
     @rcb)) then 
    begin 

     InitializeObjectAttributes(@oa, @Name, OBJ_CASE_INSENSITIVE, 0, nil); // buffer of ObjectName = 'strange character' 

    end; 

enter image description here

EDITION 2:

Окончательное решение этой проблемы, как сказал @RbMm был:

InitializeObjectAttributes(@oa, Name, OBJ_CASE_INSENSITIVE, 0, nil);

+0

Извлечь все, что необходимо, и включить все это в вопрос. Я много раз писал эту ссылку: [mcve]. Можете ли вы подтвердить, прочитали ли вы его или нет? Также, пожалуйста, прочтите следующее: http://sscce.org/ –

+0

И, наконец, в N-й раз, почему вы используете собственный API? –

+0

@DavidHeffernan, [потому что был предложен этому пользователю Луис Эдуардо] (http://stackoverflow.com/questions/41928081/how-restore-inline-hook), используйте Native api для этой задачи. –

ответ

0

Delphi уже имеет PUnicodeString тип, который отличается от PUnicodeString ваш код является определяющим. Подумайте об использовании более уникальных имен типов.

Но что более важно, входные данные, которые вы передаете RtlInitUnicodeString(), - полный гараж. Вы динамически выделяете экземпляр записи TUnicodeString с использованием неправильного размера, а затем передаете эту запись, где ожидается символьная строка.

Изменить это:

var 
    Name: PUnicodeString; 

GetMem(Name, SizeOf(Name)); 
FillChar(Name^,SizeOf(Name),#0); 
NtQueryVirtualMemory(..., Pointer(Name), MAX_PATH * SizeOf(WCHAR), ...) 
RtlInitUnicodeString(@StrUnicode, PWideChar(Name)); 
FreeMem(Name); 

Для этого:

var 
    Name: array[0..MAX_PATH-1] of WideChar; 

FillChar(Name,SizeOf(Name),#0); 
NtQueryVirtualMemory(..., @Name, SizeOf(Name), ...) 
RtlInitUnicodeString(@StrUnicode, Name); 

Или, если вы хотите использовать динамическое распределение:

var 
    Name: array of WideChar; 

SetLength(Name, MAX_PATH); 
FillChar(Name[0], Length(Name) * SizeOf(WideChar), #0); 
NtQueryVirtualMemory(..., PWideChar(Name), Length(Name) * SizeOf(WideChar), ...) 
RtlInitUnicodeString(@StrUnicode, PWideChar(Name)); 

Update: Получается вне что выход NtQueryVirtualMemory(MemoryMappedFilenameInformation) является MEMORY_MAPPED_FILE_NAME_INFORMATION структура, которая содержит UNICODE_STRING в нем:

#define _MAX_OBJECT_NAME 1024/sizeof (WCHAR) 

typedef struct _MEMORY_MAPPED_FILE_NAME_INFORMATION { 
    UNICODE_STRING Name; 
    WCHAR Buffer [_MAX_OBJECT_NAME]; 
} MEMORY_MAPPED_FILE_NAME_INFORMATION, *PMEMORY_MAPPED_FILE_NAME_INFORMATION; 

Таким образом, вы не должны даже объявить свою собственную TUnicodeString переменную на всех, просто используйте тот, который предоставляется Вам , и пусть NtQueryVirtualMemory() заселить его по мере необходимости:

const 
    _MAX_OBJECT_NAME = 1024 div sizeof(WCHAR); 

type 
    ... 

    { .: MEMORY_MAPPED_FILE_NAME_INFORMATION :. } 

    _MEMORY_MAPPED_FILE_NAME_INFORMATION = record 
    Name: TUnicodeString; 
    Buffer: array[0.._MAX_OBJECT_NAME-1] of WCHAR; 
    end; 
    MEMORY_MAPPED_FILE_NAME_INFORMATION = _MEMORY_MAPPED_FILE_NAME_INFORMATION; 
    TMemoryMappedFileNameInfo = MEMORY_MAPPED_FILE_NAME_INFORMATION; 
    PMemoryMappedFileNameInfo = ^TMemoryMappedFileNameInfo; 

... 

procedure UnhookPfn(pfn: Pointer); 
const 
    OBJ_CASE_INSENSITIVE = $00000040; 
    NtCurrentProcess = THandle(-1); 
var 
    pinth: PImageNtHeaders32; 
    fni: TMemoryMappedFileNameInfo; 
    oa: TNtObjectAttributes; 
    rcb: SIZE_T; 
begin 
    if (RtlPcToFileHeader(pfn, @hmod) <> NtNotImplementedPointer) then 
    begin 
    pinth := RtlImageNtHeader(hmod); 

    FillChar(fni, SizeOf(fni), #0); 
    fni.Name.Buffer := fni.Buffer; 
    fni.Name.Length := 0; 
    fni.Name.MaximumLength := SizeOf(fni.Buffer); 

    if (0 <= NtQueryVirtualMemory(NtCurrentProcess, Pointer(hmod), Integer(MemoryMappedFilenameInformation), @fni, SizeOf(fni), @rcb)) then 
    begin 
     InitializeObjectAttributes(@oa, @fni.Name, OBJ_CASE_INSENSITIVE, 0, nil); 
     // use oa as needed... 
    end; 
    end; 
end; 
+0

буфер, для которого точка 'PWideChar (Name)' - уже сформирована как строка Юникода. поэтому вызовите 'RtlInitUnicodeString (@StrUnicode, PWideChar (Name));' - это ошибка. но не знаю, как написать это на delphi. 'Name' ->' UNICODE_STRING', но не 'WCHAR' – RbMm

+0

Обнаружена вампирическая активность –

+1

Парень, если не нужна помощь, пожалуйста, не путайте. –

 Смежные вопросы

  • Нет связанных вопросов^_^