GetProcadDress всегда возвращается 0x00000000 после изменения dllbase в PEBC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 GetProcadDress всегда возвращается 0x00000000 после изменения dllbase в PEB

Сообщение Anonymous »

Я пытаюсь понять, почему я ничего не получаю от GetProcadDress () .
Я учился создавать свой собственный защищенный исполняемый файл. Я загружаю копию ntdll.dll и сопоставляю ее в память, а затем прочитал адрес PEB, чтобы изменить запись ntdll.dll LDR и указывать его на новую ntdll.dll .
Я делаю это только для того, чтобы увидеть, возможно ли это, потому что это будет прохладное, чтобы сменить dlls и иметь процесс использования. class = "lang-cpp prettyprint-override">void PatchNtdllInPEB(PVOID dllBase)
{
// Get the PEB using the GetPEB function
PPEB peb = reinterpret_cast
(GetPEB());
if (!peb) {
return; // Failed to get the PEB
}

// Get the loader data from the PEB
PPEB_LDR_DATA ldr = peb->Ldr;
if (!ldr) {
return; // Failed to get loader data
}

// Traverse the InMemoryOrderModuleList to find module
PLIST_ENTRY module_list = &ldr->InMemoryOrderModuleList;
for (PLIST_ENTRY list_entry = module_list->Flink; list_entry != module_list; list_entry = list_entry->Flink) {
// Get the current LDR module entry
PLDR_DATA_TABLE_ENTRY module_entry = CONTAINING_RECORD(list_entry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);

// Get the base DLL name
UNICODE_STRING base_dll_name = module_entry->BaseDllName;
if (base_dll_name.Buffer) {
// Compare with hash to find the module
if (CalculateCRC32(base_dll_name.Buffer) == 0x26797E77) {
module_entry->DllBase = dllBase;
}
}
}
}

Я изменяю dllbase , которая используется с помощью записи ntdll.dll , а затем я пытаюсь вызовать getmodulehandlea () , а затем GetProcAddress () , чтобы получить ntclose (только для проверки, сработало). Цель этого состоит в том, чтобы увидеть, смогу ли я заменить ntdll и использовать свою собственную версию.HMODULE ntdll = GetModuleHandleA("ntdll.dll");
tNtClose NtClose = (tNtClose)GetProcAddress(ntdll, "NtClose");
if (NtClose) {
NtClose(reinterpret_cast(0x2499393));
}
< /code>
Теперь я передаю недействительную ручку только для тестирования. Я ожидаю, что это потерпит неудачу, но я не ожидал, что адрес ntclose будет 0x00000000000000001 . Я ожидаю getProcadDress () , чтобы вернуть адрес ntclose . Затем это доказывает, что это сработало и что я могу сделать это. GetProcAddress () , он вызывает getProcAddressForCaller () в kernelbase.dll , а затем вызывает ldrgetProcedReadDressForCaller () , но я не вижу проблем с кодом, как это кажется нормальным. Но где -то это установлено на 0x000000000000000000 .
У меня есть ощущение, что он поступает из ntdll! Ldrgetprocedureaddressforcaller , поскольку он, кажется, возвращается, когда он возвращается. Но Windows не документирует внутреннюю работу getProcadDress () .
, когда меня спросили, как я загружаю DLL, вот код:
// Load clean ntdll.dll from KnownDlls (no disk access)
PVOID LoadCleanNtdllCopy()
{
HANDLE hSection = NULL;
PVOID baseAddress = nullptr;
UNICODE_STRING path;
WCHAR ntdllPath[] = L"\\KnownDlls\\ntdll.dll";

path.Buffer = ntdllPath;
path.Length = (USHORT)(my_wcslen(ntdllPath) * sizeof(WCHAR));
path.MaximumLength = path.Length + sizeof(WCHAR);

OBJECT_ATTRIBUTES objAttr;
InitializeObjectAttributes(&objAttr, &path, OBJ_CASE_INSENSITIVE, NULL, NULL);

// Open existing KnownDll section object
NTSTATUS status = xNtOpenSection(&hSection, SECTION_MAP_READ | SECTION_MAP_EXECUTE, &objAttr);
if (status < 0 || !hSection)
return nullptr;

SIZE_T viewSize = 0;
status = xNtMapViewOfSection(hSection,
NtCurrentProcess(),
&baseAddress,
0,
0,
NULL,
&viewSize,
ViewUnmap,
0,
PAGE_EXECUTE_READ);

xNtClose(hSection);
return baseAddress;
}

Если вы хотите сделать то же самое, что и я, просто чтобы протестировать, загрузите копию ntdll.dll , а затем исправить PEB и заменить dllbase , чтобы указать на загруженный DLL, а затем попытаться использовать GetProcAddress () , чтобы найти случайное функцию в DLL, и вы получите такую ​​же задачу. PrettyPrint-Override ">int main()
{
PVOID g_cleanNtdll = LoadCleanNtdllCopy();
if (!g_cleanNtdll)
return 0;

PatchNtdllInPEB(g_cleanNtdll);

HMODULE ntdll = GetModuleHandleA("ntdll.dll");
tNtClose NtClose = (tNtClose)GetProcAddress(ntdll, "NtClose");
if (NtClose) {
NtClose(reinterpret_cast(0x2499393));
}
}


Подробнее здесь: https://stackoverflow.com/questions/796 ... in-the-peb
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»