Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.01.16;
Скачать: CL | DM;

Вниз

Изменение таблици импорта   Найти похожие ветки 

 
Doc-N   (2004-11-14 17:58) [0]

Данная функция ищет секцию импорта модуля CallModule и меняет OrigProc на HookProc в таблице импорта. То есть теперь при вызове из модуля OrigProc импортированной функции, которую мы поменяли вызовется наша.

uses Windows, TlHelp32{$IFDEF XPALG}, ImageHlp{$ENDIF};
.....

procedure ReplaceIATEntryInOneMod(CallModulName:String; OrigProc:FARPROC; HookProc:FARPROC; CallModule:HMODULE);
var
dwSize:ULONG;
{$IFDEF XPALG}
{$ELSE}
pDosHeader:PImageDosHeader;
pNtHeader:PImageNtHeaders;
{$ENDIF}
PImportDesc:PImageImportDescriptor;
dwProtect:DWORD;
dwNewProtect:DWORD;
pThunk:PImageThunkData;
function MakePtr(base:Dword;Offset:DWORD):Pointer;
begin
Result:=Pointer(Base+Offset);
end;
begin
{$IFDEF XPALG}
PImportDesc:=ImageDirectoryEntryToData(pointer(CallModule), True, IMAGE_DIRECTORY_ENTRY_IMPORT, dwSize);
if PImportDesc=nil then Exit;

{$ELSE}
if IsBadReadPtr(Pointer(CallModule),sizeof(PImageNtHeaders)) then Exit;
pDosHeader:=PImageDosHeader(CallModule);
if pDosHeader.e_magic<>IMAGE_DOS_SIGNATURE then exit;
pNtHeader:=PImageNtHeaders(MakePtr(DWord(pDOSHeader),DWord(pDOSHeader._lfanew)));
if pNTHeader.signature<>IMAGE_NT_SIGNATURE then exit;
pImportDesc:=PImageImportDescriptor(MakePtr(CallModule, pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));

if (PImportDesc=PImageImportDescriptor(pNtHeader))  then exit;
{$ENDIF}

while PImportDesc^.Name>0 do
begin
if lstrcmpi(PChar(CallModulName),MakePtr(dword(CallModule),dword(PImportDesc^.Name)))=0 then
break
else
Inc(PImportDesc);
end;

if PImportDesc^.Name=0 then
 Exit;

pThunk:=PImageThunkData(MakePtr(DWord(CallModulName), Dword(pImportDesc^.FirstThunk)));
repeat
if pThunk^.u1.Functionn=OrigProc then // Ошибка!!! Что не так?
     begin
       if not IsBadWritePtr(Pointer(@pThunk^.u1.Functionn),sizeof(DWORD)) then
         begin
           WriteProcessMemory(GetCurrentProcess(), pThunk.u1.Functionn, @HookProc, sizeof(HookProc), dwSize);
         end
       else
         begin
           if VirtualProtect(Pointer(@pThunk.u1.Functionn),sizeof(DWORD),PAGE_EXECUTE_READWRITE,@dwProtect) then
             begin
               WriteProcessMemory(GetCurrentProcess(), pThunk.u1.Functionn, @HookProc, sizeof(HookProc), dwSize);
               dwNewProtect:=dwProtect;
               VirtualProtect(Pointer(@pThunk.u1.Functionn),sizeof(DWORD),dwNewProtect,@dwProtect);
             end;
         end;
     end;
Inc(pThunk);
until pThunk^.u1.Ordinal<>0
end;

Описания функций взяты с http://delphiworld.narod.ru/base/catch_dll_functions_calling.html

Указатель на таблицу импортов совпадает в обоих случаях (ALGXP).
Указатель на PThunk получаю вроде бы верный.
Подскажите где ошибка.
P.S.
(Рихтера уже прочитал, но ошибку все равно не нахожу)


 
Doc-N   (2004-11-14 18:00) [1]

В заглавии ошибочка - "таблицы".
Приношу свои извинения.


 
Doc-N   (2004-11-16 18:24) [2]

pThunk^<> nil
но watch показывает вместо структурі U1 nil
никто не подскажет почему?


 
Ученик   (2004-11-17 00:04) [3]

Ошибок несколько



pThunk:=PImageThunkData(MakePtr(DWord(CallModule), Dword(pImportDesc^.FirstThunk)));

WriteProcessMemory(GetCurrentProcess(), @pThunk.u1.Functionn, @HookProc, sizeof(HookProc), dwSize);

until pThunk^.u1.Ordinal=0

и цикл repeat unitl доджен быть внутри

while PImportDesc^.Name>0 do
begin

end

И неплохо бы увидеть сам вызов ReplaceIATEntryInOneMod


 
Doc-N   (2004-11-26 17:10) [4]

Увидеть вызов ReplaceIATEntryInOneMod...
Нет проблем:

procedure ReplaceIATEntryInAllMods(CallModulName:String; OrigProc:FARPROC; HookProc:FARPROC; ExcludeAPIHookMod:Boolean);
var
ThisModule:HMODULE;
h:THandle;
Me:MODULEENTRY32;
begin
 if ExcludeAPIHookMod then
  ThisModule:=HInstance//ModulFromAdress(@ReplaceIATEntryInAllMods)
 else
  ThisModule:=0;

 h:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
 if h=1 then RaiseLastOSError;

 Me.dwSize:=sizeof(MODULEENTRY32);
 Module32First(h,Me);
  if Me.hModule <> ThisModule then  //себя не трогать
   ReplaceIATEntryInOneMod(CallModulName, OrigProc, HookProc, Me.hModule);

 while Module32Next(h,Me) do
  if Me.hModule <> ThisModule then  //себя не трогать
   ReplaceIATEntryInOneMod(CallModulName, OrigProc, HookProc, Me.hModule);
end;


А вот код вообще всего модуля, может кому нибудь пригодится, как руководство что делать не надо:


unit APIHook2;

interface
uses Windows, Classes;

{$DEFINE XPALG}

{$Z4}

type
PAPIHook = ^TAPIHook;
TAPIHook = class(TObject)
   sCallModName:String;       // Module containing the function (ANSI)
   sFuncName:String;             // Function name in callee (ANSI)
   pOrig:TFarProc;                // Original function address in calleer
   pHook:TFarProc;                // Hook function address
   bExcludeAPIHookMod:Boolean;   // Hook module w/CAPIHook implementation?
 public
   // Hook a function in all modules
   constructor Create(CallModName,FuncName:String; HookProc:TFarProc; ExcludeAPIHookMod:Boolean); virtual;
   // Unhook a function from all modules
   destructor Destroy; override;
end;

var
HookList:TList;

implementation

uses SysUtils, TlHelp32{$IFDEF XPALG}, ImageHlp{$ENDIF}, tmp;

const cPushOpCode:Byte                    = $68;   // The PUSH opcode on x86 platforms
     SIZE_OF_NT_SIGNATURE                = SizeOf(DWord);
     IMAGE_MAX_SECTIONS                  = MAXWORD + 1; //Note that the Windows NT loader limits the Number of Sections to 96.
     IMAGE_MAX_IMPORT_MODULES            = MAXWORD + 1;
     IMAGE_MAX_IMPORT_MODULE_ENTRIES     = MAXWORD + 1;

var
HookGetProcAdress:TAPIHook;
HookLoadLibraryExA:TAPIHook;
HookLoadLibraryExW:TAPIHook;
HookLoadLibraryA:TAPIHook;
HookLoadLibraryW:TAPIHook;
GPAProc:TFarProc;

type

{$Z4}
// _IMAGE_IMPORT_BY_NAME
PImage_import_by_name = ^_IMAGE_IMPORT_BY_NAME;
_IMAGE_IMPORT_BY_NAME = packed record
  Hint: Word;
  Name: packed array[0..0] of char;
end;
TImage_import_by_mame = _IMAGE_IMPORT_BY_NAME;
IMAGE_IMPORT_BY_NAME  = _IMAGE_IMPORT_BY_NAME;

// _u1
_u1=packed record
case Integer of
0: (ForwarderString:PByte);
1: (Functionn:PDWORD);
2: (Ordinal: DWORD);
3: (AddressOfData:PImage_import_by_name);
end;

// _IMAGE_THUNK_DATA
PImageThunkData=^_IMAGE_THUNK_DATA;
_IMAGE_THUNK_DATA=packed record
u1:_u1;
end;
TImageThunkData  = _IMAGE_THUNK_DATA;
IMAGE_THUNK_DATA = _IMAGE_THUNK_DATA;
// THunk ThunkData
//
PImportLookupTable = ^TImportLookupTable;
TImportLookupTable = packed array[0..IMAGE_MAX_IMPORT_MODULE_ENTRIES - 1] of TImageThunkData;
//
PImportAddressTable = ^TImportAddressTable;
TImportAddressTable = packed array[0..IMAGE_MAX_IMPORT_MODULE_ENTRIES - 1] of TImageThunkData;

// _IMAGE_IMPORT_DESCRIPTOR
PImageImportDescriptor = ^TImageImportDescriptor;
_IMAGE_IMPORT_DESCRIPTOR = packed record
ImportLookupTable:PImportLookupTable;
TimeDateStamp:DWord;                  // 0 if not bound,
// -1 if bound, and real date\time stamp
//     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)
ForwarderChain:DWORD;                 // -1 if no forwarders
ImportModuleName:PChar;
ImportAddressTable:PImportAddressTable;           // RVA to IAT (if bound this IAT has actual addresses)
end;

TImageImportDescriptor = _IMAGE_IMPORT_DESCRIPTOR;
IMAGE_IMPORT_DESCRIPTOR= _IMAGE_IMPORT_DESCRIPTOR;
///////////////////////////////////////////////////////////


 
Doc-N   (2004-11-26 17:13) [5]

function GetProcAddressReal(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
type
TGPAPROC=function (hModule: windows.HMODULE; lpProcName: windows.LPCSTR): FARPROC; stdcall;
begin
Result:=tgpaproc(GPAProc)(hModule,lpProcName)
end;

procedure ReplaceIATEntryInOneMod(CallModulName:String; OrigProc:FARPROC; HookProc:FARPROC; CallModule:HMODULE);
var
peb:PPEB;
dwSize:ULONG;
dwAddressToIntercept:DWord;
{$IFDEF XPALG}
{$ELSE}
pDosHeader:PImageDosHeader;
pNtHeader:PImageNtHeaders;
{$ENDIF}
PImportDesc:PImageImportDescriptor;
dwProtect:DWORD;
dwNewProtect:DWORD;
pThunk:PImageThunkData;
function MakePtr(base:Dword;Offset:DWORD):Pointer;
begin
Result:=Pointer(Base+Offset);
end;
begin
peb:=GetCurrentPEB;
try
LockLoader(peb); //только в NT/XP
{$IFDEF XPALG}
PImportDesc:=ImageDirectoryEntryToData(pointer(CallModule), True, IMAGE_DIRECTORY_ENTRY_IMPORT, dwSize);
if PImportDesc=nil then Exit;

{$ELSE}
if IsBadReadPtr(Pointer(CallModule),sizeof(PImageNtHeaders)) then Exit;
pDosHeader:=PImageDosHeader(CallModule);
if pDosHeader.e_magic<>IMAGE_DOS_SIGNATURE then exit;
pNtHeader:=PImageNtHeaders(MakePtr(DWord(pDOSHeader),DWord(pDOSHeader._lfanew)));
if pNTHeader.signature<>IMAGE_NT_SIGNATURE then exit;
pImportDesc:=PImageImportDescriptor(MakePtr(CallModule, pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));

if (PImportDesc=PImageImportDescriptor(pNtHeader))
or (pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size=0) or
   (pNtHeader.OptionalHeader.NumberOfRvaAndSizes<16)  then exit;
{$ENDIF}

dwAddressToIntercept:=DWord(OrigProc);

while Assigned(PImportDesc^.ImportModuleName) do
begin
if lstrcmpi(PChar(CallModulName),MakePtr(dword(CallModule),dword(PImportDesc^.ImportModuleName)))=0 then
begin
 pThunk:=PImageThunkData(MakePtr(DWord(CallModule), Dword(pImportDesc^.ImportAddressTable)));
 repeat
  if DWord(pThunk^.u1.Functionn)=dwAddressToIntercept then
    begin
      if not IsBadWritePtr(Pointer(@pThunk^.u1.Functionn),sizeof(DWORD)) then
        begin
          WriteProcessMemory(GetCurrentProcess(), pThunk.u1.Functionn, @HookProc, sizeof(HookProc), dwSize);
        end
      else
        begin
          if VirtualProtect(Pointer(@pThunk.u1.Functionn),sizeof(DWORD),PAGE_EXECUTE_READWRITE,@dwProtect) then
            begin
              WriteProcessMemory(GetCurrentProcess(), pThunk.u1.Functionn, @HookProc, sizeof(HookProc), dwSize);
              dwNewProtect:=dwProtect;
              VirtualProtect(Pointer(@pThunk.u1.Functionn),sizeof(DWORD),dwNewProtect,@dwProtect);
            end;
        end;
    end;
  Inc(pThunk);
 until pThunk^.u1.Ordinal<>0;

break;
end
else
Inc(PImportDesc);
end;

finally
UnlockLoader(peb);  //только в NT/XP
end;
end;

procedure ReplaceIATEntryInAllMods(CallModulName:String; OrigProc:FARPROC; HookProc:FARPROC; ExcludeAPIHookMod:Boolean);
var
ThisModule:HMODULE;
h:THandle;
Me:MODULEENTRY32;
begin
 if ExcludeAPIHookMod then
  ThisModule:=HInstance//ModulFromAdress(@ReplaceIATEntryInAllMods)
 else
  ThisModule:=0;

 h:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
 if h=1 then RaiseLastOSError;

 Me.dwSize:=sizeof(MODULEENTRY32);
 Module32First(h,Me);
  if Me.hModule <> ThisModule then  //себя не трогать
   ReplaceIATEntryInOneMod(CallModulName, OrigProc, HookProc, Me.hModule);

 while Module32Next(h,Me) do
  if Me.hModule <> ThisModule then  //себя не трогать
   ReplaceIATEntryInOneMod(CallModulName, OrigProc, HookProc, Me.hModule);
end;

procedure FixupNewlyLoadedModule(hmod:HMODULE; dwFlags:DWORD); stdcall;
var
 I: Integer;
begin
if (hmod<>0) and ((dwFlags and LOAD_LIBRARY_AS_DATAFILE)=0) then
for I := 0 to HookList.Count - 1 do
 ReplaceIATEntryInOneMod(TAPIHook(HookList[i]).sCallModName,TAPIHook(HookList[i]).pOrig,TAPIHook(HookList[i]).pHook,hmod) ;
end;

{ TAPIHook }

constructor TAPIHook.Create(CallModName, FuncName: String;
 HookProc: TFarProc; ExcludeAPIHookMod: Boolean);
begin
HookList.Add(self);
sCallModName:=CallModName;
sFuncName:=FuncName;
pHook:=HookProc;
bExcludeAPIHookMod:=ExcludeAPIHookMod;
pOrig:=GetProcAddressReal(GetModuleHandle(pansichar(sCallModName)), pchar(sFuncName));
if pOrig=nil then
  RaiseLastOSError;
ReplaceIATEntryInAllMods(sCallModName,pOrig,pHook,bExcludeAPIHookMod);
end;

destructor TAPIHook.Destroy;
begin
 ReplaceIATEntryInAllMods(sCallModName,pHook,pOrig,bExcludeAPIHookMod);
 HookList.Remove(Self);
 inherited;
end;

function MyGetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
var
 I: Integer;
begin
Result:=GetProcAddressReal(hModule,lpProcName);
for I := 0 to HookList.Count - 1 do
if TAPIHook(HookList[i]).pOrig=Result then
 begin
  Result:=TAPIHook(HookList[i]).pHook;
  Break;
 end;
end;

function MyLoadLibraryA(lpLibFileName: PAnsiChar): HMODULE; stdcall;
type
tloadliba=function (lpLibFileName: PAnsiChar): HMODULE; stdcall;
begin
Result:=tloadliba(HookLoadLibraryA.pOrig)(lpLibFileName);
FixupNewlyLoadedModule(Result,0);
end;

function MyLoadLibraryW(lpLibFileName: PWideChar): HMODULE; stdcall;
type
tloadlibw=function (lpLibFileName: PWideChar): HMODULE; stdcall;
begin
Result:=tloadlibw(HookLoadLibraryW.pOrig)(lpLibFileName);
FixupNewlyLoadedModule(Result,0);
end;

function MyLoadLibraryExA(lpLibFileName: PAnsiChar; hFile: THandle; dwFlags: DWORD): HMODULE; stdcall;
type
tloadlibexa=function (lpLibFileName: PAnsiChar; hFile: THandle; dwFlags: DWORD): HMODULE; stdcall;
begin
Result:=tloadlibexa(HookLoadLibraryW.pOrig)(lpLibFileName, hFile, dwFlags);
FixupNewlyLoadedModule(Result,0);
end;

function MyLoadLibraryExW(lpLibFileName: PWideChar; hFile: THandle; dwFlags: DWORD): HMODULE; stdcall;
type
tloadlibexw=function (lpLibFileName: PWideChar; hFile: THandle; dwFlags: DWORD): HMODULE; stdcall;
begin
Result:=tloadlibexw(HookLoadLibraryW.pOrig)(lpLibFileName, hFile, dwFlags);
FixupNewlyLoadedModule(Result,0);
end;

var
I:Integer;
initialization
HookList:=TList.Create;
HookList.Clear;
GPAProc:=GetProcAddress(GetModuleHandle(kernel32),"GetProcAddress");
HookGetProcAdress  := TAPIHook.Create("Kernel32.dll", "GetProcAddress", @MyGetProcAddress, False);
HookLoadLibraryA   := TAPIHook.Create("Kernel32.dll", "LoadLibraryA",   @MyLoadLibraryA,   False);
HookLoadLibraryW   := TAPIHook.Create("Kernel32.dll", "LoadLibraryW",   @MyLoadLibraryW,   False);
HookLoadLibraryExA := TAPIHook.Create("Kernel32.dll", "LoadLibraryExA", @MyLoadLibraryExA, False);
HookLoadLibraryExW := TAPIHook.Create("Kernel32.dll", "LoadLibraryExW", @MyLoadLibraryExW, False);

finalization

for i:=HookList.Count-1 downto 0 do
 TAPIHook(HookList[i]).Free;

HookList.Free;
end.




 
Doc-N   (2004-11-26 17:15) [6]



//только в NT/XP
// в 98 нет :(

unit tmp;

interface
uses windows;

type
TPEB = packed record
{000}   InheritedAddressSpace : ByteBool;
{001}   ReadImageFileExecOptions : ByteBool;
{002}   BeingDebugged    : ByteBool;
{003}   SpareBool        : ByteBool;
{004}   Mutant           : Pointer;
{008}   ImageBaseAddress : Pointer;
{00C}   LdrData          : Pointer; //PPEB_LDR_DATA; { Modules list }
{010}   ProcessParameters : Pointer; //PRTL_USER_PROCESS_PARAMETERS; { _RTL_USER_PROCESS_PARAMETERS }
{014}   SubSystemData    : Pointer;
{018}   ProcessHeap      : Pointer;
{01C}   FastPebLock      : PRTLCriticalSection;
{020}   FastPebLockRoutine : Pointer;
{024}   FastPebUnlockRoutine : Pointer;
{028}   EnvironmentUpdateCount : Cardinal;
{02C}   KernelCallbackTable : Pointer;
{030}   SystemReserved   : Cardinal;
{034}   ExecuteOptions   : Cardinal; {Pos 0, 2 Bits, SpareBits  : Pos 2, 30 Bits }
{038}   FreeList         : Pointer; { _PEB_FREE_BLOCK }
{03C}   TlsExpansionCounter : Cardinal;
{040}   TlsBitmap        : Pointer;
{044}   TlsBitmapBits    : array[0..1] of Cardinal;
{04C}   ReadOnlySharedMemoryBase : Pointer;
{050}   ReadOnlySharedMemoryHeap : Pointer;
{054}   ReadOnlyStaticServerData : Pointer;
{058}   AnsiCodePageData : Pointer;
{05C}   OemCodePageData  : Pointer;
{060}   UnicodeCaseTableData : Pointer;
{064}   NumberOfProcessors : Cardinal;
{068}   NtGlobalFlag     : Cardinal;
{06C}   Reserved0        : DWord;
{070}   CriticalSectionTimeout : TLARGEINTEGER;
{078}   HeapSegmentReserve : Cardinal;
{07C}   HeapSegmentCommit : Cardinal;
{080}   HeapDeCommitTotalFreeThreshold : Cardinal;
{084}   HeapDeCommitFreeBlockThreshold : Cardinal;
{088}   NumberOfHeaps    : Cardinal;
{08C}   MaximumNumberOfHeaps : Cardinal;
{090}   ProcessHeaps     : Pointer;
{094}   GdiSharedHandleTable : Pointer;
{098}   ProcessStarterHelper : Pointer;
{09C}   GdiDCAttributeList : Cardinal;
{0A0}   LoaderLock       : PRTLCriticalSection;
{0A4}   OSMajorVersion   : Cardinal;
{0A8}   OSMinorVersion   : Cardinal;
{0AC}   OSBuildNumber    : Word;
{0AE}   OSCSDVersion     : Word;
{0B0}   OSPlatformId     : Cardinal;
{0B4}   ImageSubsystem   : Cardinal;
{0B8}   ImageSubsystemMajorVersion : Cardinal;
{0BC}   ImageSubsystemMinorVersion : Cardinal;
{0C0}   ImageProcessAffinityMask : Cardinal;
{0C4}   Reserved2        : array[0..34] of DWord;
{150}   Reserved3        : DWord;
{154}   Reserved4        : array[0..31] of DWord;
{1D4}   Win32WindowStation : THandle;
{1D8}   Reserved5        : DWord;
{1DC}   Reserved6        : DWord;
{1E0}   CSDVersion       : PWord;
{1E4}   Reserved7        : DWord;
{1E8}
end;
PPEB = ^TPEB;
////////////////////
PClientId = ^TClientId;
TClientId = record
  UniqueProcess: THandle; // Process ID
  UniqueThread: THandle;  // Thread ID
end;
CLIENT_ID = TClientId;
//////////////////////////////
PNtTib = ^TNtTib;
_NT_TIB = record
  ExceptionList       : Pointer;  // ^_EXCEPTION_REGISTRATION_RECORD
  StackBase           : Pointer;
  StackLimit          : Pointer;
  SubSystemTib        : Pointer;
  case Integer of
    0: (FiberData     : Pointer);
    1: (Version       : ULONG;
{ end; }
  ArbitraryUserPointer: Pointer;
  Self                : PNtTib);
end;
TNtTib = _NT_TIB;

///////////////////
PTeb = ^TTeb;
TTeb = packed record
  Tib               : TNtTib;
  Environment       : PWideChar;
  ClientId          : TClientId;
  RpcHandle         : THandle;
  ThreadLocalStorage: Pointer;  // PPointer
  Peb               : PPeb;
  LastErrorValue    : DWORD;
end;
_TEB = TTeb;

function GetCurrentPEB: PPEB;
procedure LockLoader(PEB: PPEB);
procedure UnlockLoader(PEB: PPEB);

implementation

function GetCurrentPEB: PPEB;
asm
mov   eax, fs:[TTeb.Peb]
//
//:    Segment override.
//Instructs the assembler that the
//expression after the colon belongs
//to the segment given by the segment
//register name (CS, DS, SS, FS, GS,
//or ES) before the colon. The result
//is a memory reference with the value
//of the expression after the colon.
//When a segment override is used in an
//instruction operand, the instruction
//is prefixed with an appropriate
//segment-override prefix instruction to
//ensure that the indicated segment is selected.
//
end;

procedure LockLoader(PEB: PPEB);
begin
EnterCriticalSection(peb^.LoaderLock^);
end;

procedure UnlockLoader(PEB: PPEB);
begin
LeaveCriticalSection(PEB^.LoaderLock^);
end;

end.



Страницы: 1 вся ветка

Текущий архив: 2005.01.16;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.025 c
6-1098805375
denissoft
2004-10-26 19:42
2005.01.16
Количество отправленных полученных байт.


4-1101439026
Ozone
2004-11-26 06:17
2005.01.16
Консольное приложение


14-1103770217
Думкин
2004-12-23 05:50
2005.01.16
С днем рождения! 23 декабря


14-1104272354
Кудесник
2004-12-29 01:19
2005.01.16
А кто такой Санта?


14-1104090808
GanibalLector
2004-12-26 22:53
2005.01.16
ТОСТ