Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.035 c
3-1102851825
aglar
2004-12-12 14:43
2005.01.16
Нумерация строк в DBGrid


14-1103872673
Чеширский_Кот
2004-12-24 10:17
2005.01.16
Good day


10-1080654787
ai
2004-03-30 17:53
2005.01.16
Быстродействие Excel


1-1104266948
RSN
2004-12-28 23:49
2005.01.16
Фокус ввода


14-1103443452
MDFE
2004-12-19 11:04
2005.01.16
NNTP сервер для delphimaster.ru (еще один клиент)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский