Форум: "WinAPI";
Текущий архив: 2005.01.23;
Скачать: [xml.tar.bz2];
ВнизПоток без длл или самодостаточный код Найти похожие ветки
← →
kaZaNoVa © (2004-11-10 18:01) [0]Идея: создать программу, которая могла бы "создавать самодостаточный код" - в плане того, чтобы возможно внедриться в другой процесс, и при этом НЕ подгружать дополнительных DLL ;)
Я давно интересовался этой темой, и только недавно нащёл реализацию:
(использованы материалы с сайта http://www.iamaphex.cjb.net)
код:
program Project1;
{$IMAGEBASE $13140000}
uses
Windows;
function Main(dwEntryPoint: Pointer): longword; stdcall;
begin
LoadLibrary("kernel32.dll");
LoadLibrary("user32.dll");
MessageBox(0, "Ok", "Hijacked Process", 0);
// ExitProcess(0);
Result := 0;
end;
procedure Inject(ProcessHandle: longword; EntryPoint: pointer);
var
Module, NewModule: Pointer;
Size, BytesWritten, TID: longword;
begin
Module := Pointer(GetModuleHandle(nil));
Size := PImageOptionalHeader(Pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(dword) + SizeOf(TImageFileHeader))).SizeOfImage;
VirtualFreeEx(ProcessHandle, Module, 0, MEM_RELEASE);
NewModule := VirtualAllocEx(ProcessHandle, Module, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(ProcessHandle, NewModule, Module, Size, BytesWritten);
CreateRemoteThread(ProcessHandle, nil, 0, EntryPoint, Module, 0, TID);
end;
var
ProcessHandle, PID: longword;
begin
GetWindowThreadProcessId(FindWindow("Progman", nil), @PID);
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
Inject(ProcessHandle, @Main);
CloseHandle(ProcessHandle);
end.
Меня интересует - всё ли в этом примере правильно - нет ли негде "подводных камней" ?
И, что будет, если в созданном потоке возникнет исключение - "процесс-носитель" в этом случае завершится ? - как в таком случае можно обрабатывать исключения ?
← →
Игорь Шевченко © (2004-11-10 18:41) [1]
> Меня интересует - всё ли в этом примере правильно - нет
> ли негде "подводных камней" ?
Практика - критерий истины.
← →
kaZaNoVa © (2004-11-10 21:01) [2]Игорь Шевченко © (10.11.04 18:41) [1]
а насчёт исключений - как можно их обработать ?
зы ОСи 2000 XP 2003 LongHorn
← →
Digitman © (2004-11-11 08:42) [3]
> нет ли негде "подводных камней" ?
начнем с этой строчки
VirtualFreeEx(ProcessHandle, Module, 0, MEM_RELEASE);
на основании чего ты уверен, что в АП целевого процесса регион с базовым адресом Module занят ? какое право ты имеешь освобождать этот регион ?
далее
NewModule := VirtualAllocEx(ProcessHandle, Module, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
ну, предположим, предыдущей строчкой ты успешно освободил регион по требуемому адресу
с чего ты взял, что размер затребованного тобой региона по адресу Module будет не менее Size ? ведь ты даже результат работы ф-ции не проверяешь ! и следом ничтоже сумняшеся пишешь в в регион Size байт, даже не зная, зарезервирован ли в действительности регион требуемого тебе размера..
это только пара самых очевидных "подводных камней", на самом деле их гораздо больше.
← →
kaZaNoVa © (2004-11-11 13:58) [4]Digitman © (11.11.04 8:42) [3]
но самое интересное, что данный код всё-же работает ...
а как правильно ??
NewModule := VirtualAllocEx(ProcessHandle,nil, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
← →
Digitman © (2004-11-11 14:13) [5]
> kaZaNoVa © (11.11.04 13:58) [4]
> данный код всё-же работает
угу. в некоем частном случае.
но тебе же ОБЩИЙ случай, думаю, нужен, а не некий частный, который сработал случайно, хоть и неоднократно ?
> а как правильно ?
а в Справке не написано разве, как правильно анализировать рез-т работы этой ф-ции ?
← →
kaZaNoVa © (2004-11-11 14:23) [6]Digitman © (11.11.04 14:13) [5]
да, нужна полная работоспособность ;))
ок .. буду рыть справку .. :)
а кстати, нуженPAGE_EXECUTE_READWRITE
илиPAGE_READWRITE
?
и почему-то в некоторых примерах MEM_COMMIT идёт без MEM_RESERVE ... ?
← →
Digitman © (2004-11-11 15:01) [7]
> нужен PAGE_EXECUTE_READWRITE или PAGE_READWRITE ?
страницы региона, содержащего маш.инструкции, предполагаемые к выполнению, обязаны иметь в числе прочих EXECUTE-флаг доступа.
> почему-то в некоторых примерах MEM_COMMIT идёт без MEM_RESERVE
вот я купил билет в оперу.
я ЗАРЕЗЕРВИРОВАЛ т.н. "место".
я могу и не прийти на шоу или опоздать на него, но при сем билет, купленный мной, по идее РЕЗЕРВИРУЕТ за мной право воспользоваться всеми теми "благами", которыми я могу (но вовсе не обязан) воспользоваться, купив этот билет..
а именно хотя бы :
- не беспокоиться за сохранность своей пальты из ангорского баклана, сданной как и положено туда, где начинается театр;
- сидеть на своем месте в театр.зале (уж это безусловно);
- дышать (театральная система кондиционирования);
- лупануть в антракте 50гр. коньячку под "икру заморскую" в тетр.буфете (на меня делается расчет);
- и т.д. и т.п.
таки явившись в оперу я реализую свое право, и некие расчитанные под меня ресурсы оперной "кухни" реально работают на меня, т.е. я сделал RESERVE + COMMIT
таки не явившись в оперу я явил собой "собаку на сене", т.е. я сделал RESERVE
← →
kaZaNoVa © (2004-11-11 15:23) [8]Digitman © (11.11.04 15:01) [7]
спасибо за обьяснение, буду разбираться ;)))
← →
Digitman © (2004-11-12 12:46) [9]
> kaZaNoVa © (11.11.04 15:23) [8]
уж не знаю, чем тебя не устраивает простой и изящный спрособ внедрения своего кода в "чужой" процесс в виде загрузки там твоей ДЛЛ, но способ, который ты сейчас пытаешься реализовать, тоже далеко не лучший - вместе с действительно необходимым кодом/данными ты "тащишь" в "чужое" АП массу ненужного там хлама, попросту бестолково отнимая эти ресурсы у того процесса.
но если таки вариант с внедрением ДЛЛ тебя никак не устраивает, в кач-ве разумной альтернативы я бы предложил след.схему
- основываясь на достаточно устойчивом факте загрузки kernel32 по фикс.адресу, получаешь адрес ф-ции kernel32.GetProcAddress()
- выделяешь удал.вирт.память расчитанного размера и записываешь туда нужные константы, следом записываешь маш.код тела поточной ф-ции
- стартуешь удаленный трэд, передавая ему параметром полученный адрес
- стартовавшая ThreadFunc первым делом получает хэндл hKernel32, накладывая маску $FFF00000 на переданный ей параметром адрес
- далее ThreadFunc вызвает GetProcAddress(hKernel32, адрес_константы_содержащей_строку_LoadLibraryA) для получения адреса точки входа в kernel32.LoadLibraryA(); отн.смещение константы со строкой "LoadLibraryA" расчитывается отн-но @ThreadFunc
- получив этот адрес ThreadFunc получает возможность определять хэндлы user32, gdi32 (и других уже загруженных сист.библ-к) и грузить прочие необходимые системные/несистемные библ-ки для обеспечения работоспособности дальнейшего своего алгоритма
Естественно, маш.код ThreadFunc() д.б. позиционно-независимым, иначе придется прибегать к тому же ненадежному способу жесткой привязки к Imagebase, который ты сейчас пытаешься реализовать
-
← →
kaZaNoVa © (2004-11-12 13:08) [10]Digitman © (12.11.04 12:46) [9]
ок, спасибо, попробую !
//вариант с длл недопустим хотя бы потому, что код будет он неё звависеть - то есть не будет "сам по себе" ;))
← →
Digitman © (2004-11-12 13:44) [11]
> код будет он неё звависеть
не выдумывай.
создай группу проектов, один проект - внедряющий ехе, другой - внедряемая ДЛЛ
в ходе разработки делай в них согласованные логические изменения, если предполагается, что внедряемая ДЛЛ будет по опред.соглашениям взаимодействовать с внедряющим ехе
строй все проекты разом, одним движением руки - build all
всех делов !
← →
kaZaNoVa © (2004-11-12 14:07) [12]Digitman © (12.11.04 13:44) [11]
с длл всё конечно хорошо :))
но моя цель сейчас реализовать именно грамотно "без длл" ;))
так как очень хочется возможности создавать удалённые потоки "чисстые" - то есть без подгрузки всяких дополнительных длл ;)))
а применение просто обширно - от реализации "чистого" перехвата апи-функций (так как например если перехватить внедрённой длл, то она будет видна в списке модулей процесса, и может дать подозрения "что с процессом что-то не то") и до реализации "изяшного" (!) способа самоудаления - например для инсталляторов, так как в результате работы кода НЕ остаётся никаких "дополнительных" длл %)
поэтому мне очень важно именно "код в памяти", я раньше думал что это невозможно, но первый пример, хоть и корявый, но рабочий доказывает то, что это ВОЗМОЖНО :))
а "код без файла" (длл, ехе)- в другом процессе - это новое слово в системном программировании !!!
("вирусные" технологии типа подмен секций и точки входа - грязно и нехорошо, а внедрение "чистого" (относительно) кода в другой процесс и работа в нём открывают поистине фантастические возможности ;))))) и при этом всё "законно" - так как никакие фацлы не изменяются и нет ничего вредного ;)))) )
← →
kaZaNoVa © (2004-11-12 14:08) [13]с длл - "вчерашний день" ;)
← →
Digitman © (2004-11-12 14:18) [14]
> "код без файла" (длл, ехе)- в другом процессе - это новое
> слово в системном программировании !!!
ой да ладно, не загибай уж ... теб более про "системное" : все эти потуги ничего общего с системным программированием не имеют
к тому же, если "суррогатный" процесс заинтересован не допустить в свой контекст "инородные тела" (типа "чужого" модуля, трэда, региона и т.д. и т.п.), то он всегда в состоянии принять для этого вполне эффективные меры. И как ты не пытайся, воткнуть в него тело своего трэда тебе в этом случае попросту не удастся
← →
kaZaNoVa © (2004-11-12 14:51) [15]Digitman © (12.11.04 12:46) [9]
> Естественно, маш.код ThreadFunc() д.б.
> позиционно-независимым, иначе придется прибегать к
> тому же ненадежному способу жесткой привязки к
> Imagebase, который ты сейчас пытаешься реализовать
а почему плох вариант с Imagebase - он же даёт возможность загружаться именно так,как нужно ;))
(легко определить, где он будет загружен :))
- нет гимора с определением адресов .. :)))
- или он (код в памяти) может загрузиться по другому адресу, игнорируя Imagebase ?
← →
kaZaNoVa © (2004-11-12 14:52) [16]Digitman © (12.11.04 14:18) [14]
а какие меры он может предпринять ?
← →
Digitman © (2004-11-12 15:35) [17]
> а почему плох вариант с Imagebase
я тебе уже сказал - ненадежность.
сегодня сработал (регион нужного размера оказался незанятым), завтра не сработал.... и нафих такой код нужен, гарантия успешной работы которого заведомо не 100%-на ? причем по независящим от тебя причинам ?
> легко определить, где он будет загружен
что там определять-то ? ты сам и говоришь системе, куда ты влупить свой код хочешь ... только вот система вовсе не обязана "выпихивать" с требуемого тебе места того кто там уже до тебя "поселился", если факт обнаружится, ситема просто вернет тебе отлуп в ответ на VirtualAllocEx и ты сел в лужу - что дальше делать будешь ?
> или он (код в памяти) может загрузиться по другому адресу,
> игнорируя Imagebase
с какого перепугу-то ? ты же явно говоришь системе : мне, мол, надыть регион размером в 100мб начиная с $13140000 ..
вот если ты скажешь, что тебе надо те же 100мб где угодно (т.е. где найдется местечко), вот тогда система либо найдет такое местечко и скажет тебе его адрес либо ты опять же получишь отлуп
← →
kaZaNoVa © (2004-11-12 21:55) [18]- основываясь на достаточно устойчивом факте загрузки kernel32 по фикс.адресу, получаешь адрес ф-ции kernel32.GetProcAddress()
а как ?Cardinal(@GetProcAddress)
?
> - далее ThreadFunc вызвает GetProcAddress(hKernel32,
> адрес_константы_содержащей_строку_LoadLibraryA) для
> получения адреса точки входа в
> kernel32.LoadLibraryA(); отн.смещение константы со
> строкой "LoadLibraryA" расчитывается отн-но @ThreadFunc
а как расчитывается это смещение ?
(добавать 11771 ?)
← →
kaZaNoVa © (2004-11-15 00:32) [19]или может попробывать добавлять по 1 - и каждый раз пробовать вызывать функцию .. хотя, не, это изврат ..
← →
Digitman © (2004-11-15 08:36) [20]
> а как ?
> Cardinal(@GetProcAddress) ?
GetProcAddress(hKernel32, "GetProcAddress");
> добавать 11771
что такое 11771 ?
> как расчитывается это смещение
есть масса самых разных способов
← →
kaZaNoVa © (2004-11-15 12:21) [21]
> - основываясь на достаточно устойчивом факте загрузки
> kernel32 по фикс.адресу, получаешь адрес ф-ции
> kernel32.GetProcAddress()
а какой этот адрес ?
>> как расчитывается это смещение
>
>
> есть масса самых разных способов
какие ?
> что такое 11771 ?
это я сравнивал адреса разных функций, одно из смещений ...
← →
Digitman © (2004-11-15 12:35) [22]
> а какой этот адрес ?
какая тебе разница, "какой" он ? важно что этот адрес должен иметь одно и то же значение для любого win32-процесса, использующего модуль kernel32
> какие ?
например, в "чужом" АП в ходе выполнения ThreadFunc определить адрес X т.входа в "саму себя" .. и если известно, что перед непосредственно телом ThreadFunc находится некая структура размером в Y байт, то смещение абс.адреса начала этой структуры будет равно X - Y
← →
kaZaNoVa © (2004-11-15 13:07) [23]тут я попробовал залезть в память "целевого" процесса и посмотреть, что там по загружаемому адресу находидится (лазил через Редактор Памяти ArtMoney) - и обнаружил там мой ЕХЕшник целеком ;))
прикольно .. :)
(поначалу не ожидал, думал что будет только код нужной процедуры ..)
Всё-таки сама эта моя идея "самостоятельный поток в чужом процессе" сейчас мне кажется немного "бредовой", но она , как я уже убедился, реализуема ;)
только бы хотелось бы по грамотнее реализовать .. :)
---
тут я на одном форуме видел обсуждения подобной идеи:
----
загрузить модуль, скопировать всю память модуля в "карман"
выгрузить модуль, произвести аллокацию по тому же адресу, и скопировать память обратно. Правда здесь не факт, что я смогу аллоцировтаь память по тому же адресу.
------
Не сможешь по тому адресу (хотя должОн смочь) - сможешь по другому. Потом придется только reloc поправить :) Вот только если ты его скопируешь целиком, то можно будет распознать MZ/PE заголовок, и таким образом узнать о наличии постороннего модуля. С другой стороны, ты можешь и сам этот заголовок подпортить... А с третьей стороны, я, как админ, тебя за такие идеи "убыв бы!" :-E
-----
ну насчет - смогу по другому - не хоцца мне релоки править.
-----
там они так и не реализовали .. (а может и реализовали, но не запостили ;((
← →
kaZaNoVa © (2004-11-15 13:22) [24]Digitman © (15.11.04 12:35) [22]
>> а какой этот адрес ?
>
>
> какая тебе разница, "какой" он ? важно что этот адрес
> должен иметь одно и то же значение для любого
> win32-процесса, использующего модуль kernel32
нашёл, кажется 2011430912 (в десятичной системе)
или 0x77E40000 ;))
а что значит:
> - стартовавшая ThreadFunc первым делом получает хэндл
> hKernel32, накладывая маску $FFF00000 на переданный ей
> параметром адрес
как такую маску наложить ?(integer(dwEntryPoint) xor $FFF00000)
?
← →
Digitman © (2004-11-15 13:27) [25]
> обнаружил там мой ЕХЕшник целеком ;))
> прикольно .. :)
> (поначалу не ожидал, думал что будет только код нужной
> процедуры ..)
что ж "прикольного" ?
тебе еще в [9] об этом сказано
> хотелось бы по грамотнее реализовать
"грамотная" реализация сводится к размещению в "чужом" АП всего того что минимально необходимо для корректной работы стартуемого там трэда, а так же позиционная независимость кода этого трэда, если это необходимо.
← →
kaZaNoVa © (2004-11-15 14:02) [26]эх ... что-то ничего у меня с м "изменяющимися" адресами функций не вышло ..
сделал так:
program loader;
{$IMAGEBASE $72780000}
uses
Windows,Tlhelp32;
function Main1(dwEntryPoint: Pointer): longword; stdcall;
begin
LoadLibrary("kernel32.dll");
LoadLibrary("user32.dll");
MessageBox(0, "Ok", "Hijacked Process", 0);
// ExitProcess(0);
Result := 0;
end;
function SetDebugPriv: Boolean;
var
Token: THandle;
tkp: TTokenPrivileges;
begin
Result := false;
if OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then
begin
if LookupPrivilegeValue(nil, PChar("SeDebugPrivilege"), tkp.Privileges[0].Luid) then
begin
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
Result := AdjustTokenPrivileges(Token, false, tkp, 0, PTokenPrivileges(nil)^, PDWord(nil)^);
end;
end;
end;
function Start(ProcessID: Cardinal; DllFileName: string): Boolean;
var
hProcess, hTh: THandle;
BytesWritten, ThreadID: Cardinal;
MemPtr: Pointer;
ExitCode: DWord;
Size: longword;
Module: Pointer;
begin
Module := Pointer(GetModuleHandle(nil));
Size := PImageOptionalHeader(Pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(dword) + SizeOf(TImageFileHeader))).SizeOfImage;
Result := false;
SetDebugPriv();
hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE,true, ProcessID);
if hProcess <> 0 then
begin
BytesWritten:=0;
VirtualFreeEx(hProcess, Module, 0, MEM_RELEASE);
MemPtr := VirtualAllocEx(hProcess,Module, Size , MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE );
if MemPtr <> nil then
begin
if WriteProcessMemory(hProcess, MemPtr,Module, Size, BytesWritten) then
begin
hTh := CreateRemoteThread(hProcess, nil, 0,Pointer(Integer(@Main1)-Integer(Module)+Integer(MemPtr)),MemPtr, 0, ThreadID);
if hTh <> 0 then
begin
if (WaitForSingleObject(hTh, INFINITE) = WAIT_OBJECT_0) and
GetExitCodeThread(hTh, ExitCode) then
Result := ExitCode <> 0;
CloseHandle(hTh);
end;
end;
VirtualFreeEx(hProcess, MemPtr, 0, MEM_RELEASE);
end;
CloseHandle(hProcess);
end;
end;
function UpperCase(const S: string): string;
var I : Integer;
begin
Result := S;
for I := 1 to Length( S ) do
if Result[ I ] in [ "a".."z" ] then
Dec( Result[ I ], 32 );
end;
var
ProcessID: Cardinal;
DllName,ppp: string;
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
ProcessID:=0;
FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle,FProcessEntry32);
while integer(ContinueLoop) <> 0 do
begin
ppp:=FProcessEntry32.szExeFile;
if (pos("CALC.EXE",UpperCase(ppp))>0) then ProcessID:=FProcessEntry32.th32ProcessID;
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
if ProcessID <> 0 then Start(ProcessID, DllName);
end.
думаю, вероятность того, что $72780000 будет занят - очень мала ..
пока везде, где запускал - код работает ...
буду тестировать на разных процессах ...
← →
Digitman © (2004-11-15 14:19) [27]каша у тебя в голове..
и опять ты пытаешься влупить в чужое АП образ всего своего ехе-модуля .. и опять - в предположении о фиксированном его Imagebase
спрашивается, на кой шут все эти выкрутасы с
Pointer(Integer(@Main1)-Integer(Module)+Integer(MemPtr))
и пр.
?
> думаю, вероятность
до тех пор пока ты полагаешься в этом деле на "вероятность", ничего путного у тебя не выйдет
← →
kaZaNoVa © (2004-11-15 15:12) [28]Digitman © (15.11.04 14:19) [27]
> каша у тебя в голове..
да уж .. надо справку почитать ..
> и опять ты пытаешься влупить в чужое АП образ всего
> своего ехе-модуля .. и опять - в предположении о
> фиксированном его Imagebase
так как у меня маленький ехе (15-20 кб) я думаю, что ничего плохого не будет, если загружу его целиком ..
у меня появился ОЧЕНЬ важный вопрос, а что будет если я свой ехе упакую UPX ?
> Pointer(Integer(@Main1)-Integer(Module)+Integer(MemPtr)
> )
осталось от старой попытки загрузить по другому адресу ...
← →
Digitman © (2004-11-15 15:26) [29]
> kaZaNoVa © (15.11.04 15:12) [28]
> у меня маленький
ты о ран-тайм-пакетах что-нть слыхал ?
> что будет если я свой ехе упакую UPX ?
ничего не будет.
это - из другой оперы.
> осталось от старой попытки
и долго ты тут будешь захламлять ветку, без конца дублируя код от "старых попыток" ? например, код установки привелегий чего-то там, НЕ имеющий к сабжу никакого отношения ?
← →
kaZaNoVa © (2004-11-15 15:28) [30]Digitman © (15.11.04 15:26) [29]
> ты о ран-тайм-пакетах что-нть слыхал ?
слыхал .. но это имхо не то ..
(их таскать за собой придётся ...)
← →
kaZaNoVa © (2004-11-15 15:29) [31]
Function I(t:cardinal):string;
Begin
Str(t,Result);
End;
function ThreadF1(dwEntryPoint: Pointer): longword; stdcall;
Var t:string;
begin
LoadLibrary("kernel32.dll");
LoadLibrary("user32.dll");
sleep(500);
t:="1";
t:=i(1);
Result := 0;
end;
такой код выдаёт исключение .. странно ..
← →
kaZaNoVa © (2004-11-15 15:30) [32]Digitman © (15.11.04 15:26) [29]
> и долго ты тут будешь захламлять ветку, без конца
> дублируя код от "старых попыток" ? например, код
> установки привелегий чего-то там, НЕ имеющий к сабжу
> никакого отношения ?
постараюсь приводить только "значимый" код ;)))
← →
Digitman © (2004-11-15 15:38) [33]
> kaZaNoVa © (15.11.04 15:28) [30]
> слыхал .. но это имхо не то ..
> (их таскать за собой придётся ...)
и это все что ты знаешь о ран-тайм пакетах ? применительно к поднятой тобой теме ?
те самые 15-20к твоего ехе - это ВЕСЬ код ? или код в расчете на использование кода из ран-тайм пакетов ?
← →
kaZaNoVa © (2004-11-15 15:40) [34]Digitman © (15.11.04 15:38) [33]
> те самые 15-20к твоего ехе - это ВЕСЬ код ? или код в
> расчете на использование кода из ран-тайм пакетов ?
весь код ...
← →
Digitman © (2004-11-15 16:11) [35]
> kaZaNoVa © (15.11.04 15:40) [34]
слушай, я устал уже.
говорим на совершенно разных языках.
последний вопрос в надежде восстановить "понимание" - в опциях проекта, в котором ты пытаешься "влупить" некий код в "чужое" АП, галка "Build With Run-Time Packages" стоит или "висит" ?
← →
kaZaNoVa © (2004-11-15 16:16) [36]галки НЕТ
← →
kaZaNoVa © (2004-11-15 16:18) [37]а как отлаживать его ?
(код в чужом процессе ?)
и я почему-то не могу преобразовать cardinal в string . . выдвётся исключение
← →
Digitman © (2004-11-15 16:36) [38]
> галки НЕТ
щзначит, остается проблема "статики".
> как отлаживать его ?
вопрос отдельный.
> почему-то не могу преобразовать cardinal в string
с какого перепугу "cardinal в string" преобразуется ?
← →
kaZaNoVa © (2004-11-15 16:51) [39]Digitman © (15.11.04 16:36) [38]
мне надо отладить ..
как ? %_)))
> с какого перепугу "cardinal в string" преобразуется ?
Function I(t:cardinal):string;
Begin
Str(t,result);
End;
← →
kaZaNoVa © (2004-11-15 16:52) [40]я хотел все адреса (Pointer"ы) - преобразовать в стринги и вывести мессагебоксом .. - в целях отладки ...
Страницы: 1 2 3 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.01.23;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.054 c