Нужно вызвать 64 битную функцию из 32 битного приложения. В частности: SetWindowLongPtr Если вызвать 32 битную, то данная функция меняет только нижние 32 бита поля в удаленном 64 битном процессе. У кого какие идеи? =)
o Делегировать задачу отдельному 64х-битному процессу. o Использовать переходник для прыжка в 64х-разрядный сегмент (far call), подгрузить нужные 64х-разрядные библиотеки и вызвать апи, затем вернуться в 32х-разрядный сегмент (retf). Библиотека ntdll x64 в просессах x32 присутствует, так что native api доступен. Данный подход применялся партнёром нас (актуально, эта сущность делала высказывания о возможности автоматизировать весь процесс вызова х64-апи, но дальше двойной компиляции приплюснутого кода и слинковывания в один экзешник х32 и х64 объектников дело, насколько нам известно, до сих по не зашло). [Привет, Huey]. Одно предупреждение – в последнем случае нужно соблюдать некоторые правила (волатильность регистров, выравнивание стека, CC, etc).
Делегировать задачу или делать через СОМ ддлку не очень хочется. А кусочек кода или псевдокода можно? То есть что бы было с чего начать. К примеру куда прыгать переходником то.
Legacy Mode: Код (Text): #define KGDT_NULL (0x00) #define KGDT_R0_CODE (0x08) #define KGDT_R0_DATA (0x10) #define KGDT_R3_CODE (0x18) <- Ты здесь (Legacy Mode). #define KGDT_R3_DATA (0x20) #define KGDT_TSS (0x28) #define KGDT_R0_PCR (0x30) #define KGDT_R3_TEB (0x38) #define KGDT_R3_VDM (0x40) #define KGDT_LDT (0x48) #define KGDT_DF_TSS (0x50) #define KGDT_NMI_TSS (0x58) Long Mode: Код (Text): #define KGDT64_NULL (0x00) #define KGDT64_R0_CODE (0x10) #define KGDT64_R0_DATA (0x18) #define KGDT64_R3_CMCODE (0x20) <- Ты здесь (Compatibility Mode). #define KGDT64_R3_DATA (0x28) #define KGDT64_R3_CODE (0x30) <- Тебе надо сюда (x64 Mode). #define KGDT64_SYS_TSS (0x40) #define KGDT64_R3_CMTEB (0x50) #define KGDT64_R0_CMCODE (0x60) #define KGDT64_LAST (0x70) Простейший пример – получение адреса и лимита GDT для текущего процессора из Legacy\Compatibility mode. Код (Text): PUVOID64 FASTCALL GetGdt(DWORD* Limit = NULL); GetGdt: xor edx, edx mov ax, cs push edx push edx push edx sgdt [esp + 2] cmp al, $23 ; KGDT64_R3_CMCODE | RPL_MASK jne @f call 0x33:GetGdt_x64Mode ; KGDT64_R3_CODE | RPL_MASK @@: pop edx shr edx, 10h test ecx, ecx jz @f mov [ecx], edx @@: pop eax pop edx retn GetGdt_x64Mode: ; ; Всё, мы в подрежиме x64. ; Необходимо заметить, что здесь мы даже не переключили режим генерации ассемблерных команд – таким образом, ; на самом деле выполняются инструкции "sgdt [rsp + 8 + 2]; retfd;". Если бы кусок кода был больше, можно было ; бы переключить режим ассемблирования в этом месте – для фасма используется директива "use64". ; Также необходимо обратить внимание на то, что для выхода используется "retfd" – дальний ret с 32х-разрядным ; размером операнда. Это для того, чтобы соответствовать разрядности операнда начального call far. ; sgdt [esp + 8 + 2] ; call pushed 2 dwords on stack retfd Также прикладываем микротулзу для базового конверта х64-объектников в 32х-разрядные, для дальнейшей прилинковки стандартным компоновщиком от MS. P.S. Надеемся вскоре увидеть качественный кросплатформенный продукт. Лол.
Загрузив дллки в процесс, получил: 400000 4bb1bd1c Mar 30 11:58:04 2010 Z:\Share\main.exe 77ec0000 49901574 Feb 09 13:37:24 2009 C:\WINDOWS\system32\ntdll.dll 78be0000 42438b79 Mar 25 05:54:33 2005 C:\WINDOWS\system32\wow64.dll 78b90000 42438b79 Mar 25 05:54:33 2005 C:\WINDOWS\system32\wow64win.dll 78b80000 42438b7a Mar 25 05:54:34 2005 C:\WINDOWS\system32\wow64cpu.dll 3870000 49c52144 Mar 21 19:17:56 2009 C:\WINDOWS\System32\kernel32.dll 39f0000 45e7bfcb Mar 02 08:10:19 2007 C:\WINDOWS\System32\user32.dll 3b00000 49006dd0 Oct 23 15:28:00 2008 C:\WINDOWS\system32\GDI32.dll Вопрос: как сделать что бы 64 битные либы загрузились по оригинальным адресам? По тем что они загрузились они фурычить не хотят. (Грузил либы через LdrLoadDll)
Да, сейчас проверили – верхние адреса действительно зарезервированы: Код (Text): lkd> !process 0 1 notepad.exe PROCESS fffffa8002015b30 SessionId: 3 Cid: 0f50 Peb: 7efdf000 ParentCid: 0eb4 DirBase: 53fe1000 ObjectTable: fffff8a0107f3c30 HandleCount: 0. Image: notepad.exe VadRoot fffffa80044de5b0 Vads 18 Clone 0 Private 23. Modified 0. Locked 0. DeviceMap 0000000000000000 Token fffff8a0041f8510 ElapsedTime 00:01:00.397 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 0 QuotaPoolUsage[NonPagedPool] 0 Working Set Sizes (now,min,max) (43, 50, 345) (172KB, 200KB, 1380KB) PeakWorkingSetSize 43 VirtualSize 4 Mb PeakVirtualSize 4 Mb PageFaultCount 38 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 108 DebugPort fffffa80044ad060 lkd> !vad fffffa80044de5b0 VAD level start end commit fffffa800499dc70 ( 4) 10 2f 32 Private READWRITE fffffa8003d75980 ( 3) 30 31 2 Private READWRITE fffffa8003bfc010 ( 2) 40 40 0 Mapped Exe EXECUTE_WRITECOPY \Windows\System32\apisetschema.dll fffffa800478c950 ( 4) 50 53 0 Mapped READONLY Pagefile-backed section fffffa8002ac90e0 ( 3) 60 61 0 Mapped READONLY Pagefile-backed section fffffa8002519590 ( 4) 70 70 1 Private READWRITE fffffa8001b9dda0 ( 1) a0 df 7 Private READWRITE fffffa800454b2e0 ( 3) 2a0 2df 19 Private READWRITE fffffa8004717f80 ( 2) 300 32f 3 Mapped Exe EXECUTE_WRITECOPY \Windows\SysWOW64\notepad.exe fffffa80044f9390 ( 3) 77bc0 77d6a 13 Mapped Exe EXECUTE_WRITECOPY \Windows\System32\ntdll.dll fffffa8002feea40 ( 4) 77da0 77f1f 9 Mapped Exe EXECUTE_WRITECOPY \Windows\SysWOW64\ntdll.dll fffffa80044de5b0 ( 0) 7efb0 7efd2 0 Mapped READONLY Pagefile-backed section fffffa800204b930 ( 3) 7efdb 7efdd 3 Private READWRITE fffffa8004325b90 ( 2) 7efde 7efde 1 Private READWRITE fffffa80044c9c30 ( 3) 7efdf 7efdf 1 Private READWRITE fffffa8004446e00 ( 1) 7efe0 7ffdf 0 Private READONLY fffffa8001d96010 ( 2) 7ffe0 7ffef -1 Private READONLY fffffa8002a3e380 ( 3) 7fff0 7fffffef -1 Private READONLY Total VADs: 18 average level: 3 maximum depth: 4 lkd> !vad fffffa8002a3e380 1 VAD @ fffffa8002a3e380 Start VPN 7fff0 End VPN 7fffffef Control Area 0000000000000000 FirstProtoPte 0000000000000000 LastPte 0000000000000000 Commit Charge ffffffff (-1.) Secured.Flink 7fff0001 Blink 7fffffeffff Banked/Extend 0 File Offset 0 ViewUnmap NoChange PrivateMemory READONLY OneSecured Посмотри на последний VAD. Он описывает регион адресного пространства 7fff_0000...7ff`fffe_ffff. Кроме того, обрати внимание на флаги: 'NoChange' говорит о том, что нельзя менять атрибуты защиты страниц, а 'OneSecured' – о том, что участок Secured.Flink...Blink застрахован. Короче говоря, освободить этот огромный регион не получится. Хотя можно расширить доступное для 32х-битного приложения АП до 4х гигабайт, установив соответствующий флаг в хидере главного модуля процесса (/LargeAddressAware). Судя по немедленному отсутствию ненативной ntdll и базе kernel32 это у тебя nt5? Что за версия? Странно, что kernel32 промапилась по такому адресу – по идее даже у 64х-битных версий её дефолтная база ниже 2GB. ziral2088 >как сделать что бы 64 битные либы загрузились по оригинальным адресам? По тем что они загрузились они фурычить не хотят. Вывод о неработоспособности из-за релокации выглядит преждевременным. Копай глубже
До этого грузил ддлки так: LdrLoadDll kenrel32 LdrLoadDll user32 Попробовал сразу загрузить user32, в итоге получил ошибку.
ziral2088 Загрузчик перед выполнением релокации модулей в LdrpMapDll() проверяет имя, если это Kernel32 или User32(пер. Kernel32String и User32String соответственно), то генерирует исключение STATUS_ILLEGAL_DLL_RELOCATION - для этих двух модулей не может применяться релокация, так как в них ссылки глобальные в системе(для всех процессов). Вам нужно изменить имена модулей.
Clerk >user32 Это наверное только на nt5. В w7 (да и в висте, IWRC) user32.dll может релоцироваться. На самом деле неясно, почему до сих пор присутствует проверка базы kernel32.dll – возможно, для совместимости с пользовательским кодом, полагающимся на неперемещаемость этой длл. [Упреждая "стартовый адрес потока" (который _ethread.StartAddress): сейчас вместо kernel32!BaseProcessStartThunk \ kernel32!BaseThreadStartThunk используется единообразный ntdll!RtlUserThreadStart]. ziral2088 Тотально окей запросить базовую информацию для старта. Но направлять каждый шаг не будет никто – особенно когда направляемый игнорирует вопросы. И ты правда хочешь завершить иллегальное кроссбитное нечто и при этом не можешь воспользоваться ни отладчиком, ни mspaint'ом? Серьёзно, на этом этапе нам начинает казаться, что тебе лучше бросить это – гоккокода в Сети и так хватает.