Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Доступ в Ring0 под Windows 9x, переводим "сишный" код на Паскаль 
:(
    Опции темы
jungle
Дата 26.6.2006, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аппаратный кодер



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.1.2006
Где: Беларусь

Репутация: нет
Всего: нет



Хэллоу, друзья! 

Помогите корректно перевести сишный сорсис для доступа в привилегированный режим ядра Windows 9x – Ring0. Мой перевод, увы, пока не работает. Может быть кто-то силён в Си и Delphi (паскаль) одновременно? Исходный cpp код в прикреплении.

Код

unit Ring09x;

interface

uses
  Windows;

  function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer;
  procedure Ring0ReadMSR; cdecl;

implementation

type

  TGDT_DESCRIPTOR = record
    Limit_0_15  : Word;
    Base_0_15   : Word;
    Base_16_23  : Byte;
    Type1       : Byte;
    System1     : Byte;
    DPL         : Byte;
    Present     : Byte;
    Limit_16_19 : Byte;
    Available   : Byte;
    Reserved    : Byte;
    D_B         : Byte;
    Granularity : Byte;
    Base_24_31  : Byte;
  end;

  TCALLGATE_DESCRIPTOR = record
    Offset_0_15 : Word;
    Selector    : Word;
    ParamCount  : Word;
    Unused      : Word;
    Type1       : Word;
    System1     : Word;
    DPL         : Word;
    Present     : Word;
    Offset_16_31: Word;
  end;

  TGDTR = record
    wGDTLimit : Word;
    dwGDTBase : Word;
  end;

procedure Ring0ReadMSR; cdecl;
asm
  rdmsr
  mov [ebx],eax
  mov [edi],edx
end;

procedure Ring0WriteMSR; cdecl;
asm
  mov eax,[ebx]
  mov edx,[edi]
  wrmsr
end;

function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer;
var
  pGDTDescriptor : ^TGDT_DESCRIPTOR;
  pCallgate : ^TCALLGATE_DESCRIPTOR;
  gdtr: TGDTR;
  wGDTIndex : Integer;
  CallgateAddr : array [0..2] of Word;
begin
  with pGDTDescriptor^ do begin
    Type1:=4;
    System1:=1;
    DPL:=2;
    Present:=1;
    Limit_16_19:=4;
    Available:=1;
    Reserved:=1;
    D_B:=1;
    Granularity:=1;
  end;
  with pCallgate^ do begin
    ParamCount:=5;
    Unused:=3;
    Type1:=4;
    System1:=1;
    DPL:=2;
    Present:=1;
  end;
  asm sgdt [gdtr] end;
  pGDTDescriptor:=ptr(gdtr.dwGDTBase + 8);
  wGDTIndex:=1;
  while wGDTIndex < (gdtr.wGDTLimit div 8) do
    begin
      if (pGDTDescriptor.Type1 = 0) and (pGDTDescriptor.System1 = 0) and
        (pGDTDescriptor.DPL = 0)  and (pGDTDescriptor.Present = 0) then
        begin
          pCallgate:=Addr(pGDTDescriptor);
          pCallgate.Offset_0_15:=LoWord(pvRing0FuncAddr);
          pCallgate.Selector:=$28;
          pCallgate.ParamCount:=0;
          pCallgate.Unused:=0;
          pCallgate.Type1:=$0C;
          pCallgate.System1:=0;
          pCallgate.DPL:=3;
          pCallgate.Present:=1;
          pCallgate.Offset_16_31:=HiWord(DWORD(pvRing0FuncAddr));
          CallgateAddr[0]:=0;
          CallgateAddr[1]:=0;
          CallgateAddr[2]:=(wGDTIndex shl 3) or 3;
          asm
            mov ebx, pulEAX
            mov edi, pulEDX
            mov ecx, ulECX
            call dword ptr [CallgateAddr]
          end;
          ZeroMemory(pGDTDescriptor, 8);
        end;
      Inc(pGDTDescriptor);
      Inc(wGDTIndex);
    end;
end;

end.


 

Присоединённый файл ( Кол-во скачиваний: 12 )
Присоединённый файл  MSR9X.cpp.zip 2,19 Kb
PM MAIL WWW   Вверх
Romikgy
Дата 26.6.2006, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Код

type
CALLGATE_DESCRIPTOR=^TCALLGATE_DESCRIPTOR;

function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer;
var    
  pGDTDescriptor : ^TGDT_DESCRIPTOR;    
  pCallgate : ^TCALLGATE_DESCRIPTOR;    
  gdtr: TGDTR;    
  wGDTIndex : Integer;    
  CallgateAddr : array [0..2] of Word;    
begin    

  asm sgdt [gdtr] end;    
  pGDTDescriptor:=ptr(gdtr.dwGDTBase + 8);    
  for wGDTIndex:=1 to (gdtr.wGDTLimit/8) do
    begin    
      if (pGDTDescriptor^.Type1 = 0) and (pGDTDescriptor^.System1 = 0) and
        (pGDTDescriptor^.DPL = 0)  and (pGDTDescriptor^.Present = 0) then
        begin    
          pCallgate:=CALLGATE_DESCRIPTOR(pGDTDescriptor);
          pCallgate^.Offset_0_15:=LoWord(pvRing0FuncAddr);
          pCallgate^.Selector:=$28;
          pCallgate^.ParamCount:=0;
          pCallgate^.Unused:=0;
          pCallgate^.Type1:=$0C;
          pCallgate^.System1:=0;
          pCallgate^.DPL:=3;
          pCallgate^.Present:=1;
          pCallgate^.Offset_16_31:=HiWord(DWORD(pvRing0FuncAddr));
          CallgateAddr[0]:=0;    
          CallgateAddr[1]:=0;    
          CallgateAddr[2]:=(wGDTIndex shl 3) or 3;    
          asm    
            mov ebx, pulEAX    
            mov edi, pulEDX    
            mov ecx, ulECX    
            call dword ptr [CallgateAddr]    
          end;    
          ZeroMemory(pGDTDescriptor, 8);    
          CallRing0:=1;
          exit;
        end;    
      Inc(pGDTDescriptor);    
      //Inc(wGDTIndex);
    end;    
    CallRing0:=0;
end;

Имхо так smile 
вроде не ошибся 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
jungle
Дата 26.6.2006, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аппаратный кодер



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.1.2006
Где: Беларусь

Репутация: нет
Всего: нет



Romikgy
Пишет Incompatible types для строчки pCallgate:=CALLGATE_DESCRIPTOR(pGDTDescriptor); smile  

О! Надо просто было объявить переменную pCallgate : CALLGATE_DESCRIPTOR;

Сейчас заценим под Windows 9x на другой машине…

Добавлено @ 11:51 
Romikgy

Неа, не катит - исключение "ошибка доступа... Запись данных по адресу". Код обновил.

Код

unit Ring09x;

interface

uses
  Windows;

  function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer;
  procedure Ring0ReadMSR; cdecl;

implementation

type

  TGDT_DESCRIPTOR = record
    Limit_0_15  : Word;
    Base_0_15   : Word;
    Base_16_23  : Byte;
    Type1       : Byte;
    System1     : Byte;
    DPL         : Byte;
    Present     : Byte;
    Limit_16_19 : Byte;
    Available   : Byte;
    Reserved    : Byte;
    D_B         : Byte;
    Granularity : Byte;
    Base_24_31  : Byte;
  end;

  TCALLGATE_DESCRIPTOR = record
    Offset_0_15 : Word;
    Selector    : Word;
    ParamCount  : Word;
    Unused      : Word;
    Type1       : Word;
    System1     : Word;
    DPL         : Word;
    Present     : Word;
    Offset_16_31: Word;
  end;
  CALLGATE_DESCRIPTOR=^TCALLGATE_DESCRIPTOR;

  TGDTR = record
    wGDTLimit : Word;
    dwGDTBase : Word;
  end;

procedure Ring0ReadMSR; cdecl;
asm
  rdmsr
  mov [ebx],eax
  mov [edi],edx
end;

procedure Ring0WriteMSR; cdecl;
asm
  mov eax,[ebx]
  mov edx,[edi]
  wrmsr
end;

function CallRing0(pvRing0FuncAddr: Pointer; ulECX: DWORD; pulEAX: pULONG; pulEDX: pULONG): integer;
var
  pGDTDescriptor : ^TGDT_DESCRIPTOR;
  pCallgate : CALLGATE_DESCRIPTOR;
  gdtr: TGDTR;
  wGDTIndex : Integer;    
  CallgateAddr : array [0..2] of Word;
begin
  with pGDTDescriptor^ do begin
    Type1:=4;
    System1:=1;
    DPL:=2;
    Present:=1;
    Limit_16_19:=4;
    Available:=1;
    Reserved:=1;
    D_B:=1;
    Granularity:=1;
  end;
  with pCallgate^ do begin
    ParamCount:=5;
    Unused:=3;
    Type1:=4;
    System1:=1;
    DPL:=2;
    Present:=1;
  end;
  asm sgdt [gdtr] end;    
  pGDTDescriptor:=ptr(gdtr.dwGDTBase + 8);    
  for wGDTIndex:=1 to (gdtr.wGDTLimit div 8) do
    begin    
      if (pGDTDescriptor^.Type1 = 0) and (pGDTDescriptor^.System1 = 0) and
        (pGDTDescriptor^.DPL = 0)  and (pGDTDescriptor^.Present = 0) then
        begin
          pCallgate:=CALLGATE_DESCRIPTOR(pGDTDescriptor);
          pCallgate^.Offset_0_15:=LoWord(pvRing0FuncAddr);
          pCallgate^.Selector:=$28;
          pCallgate^.ParamCount:=0;
          pCallgate^.Unused:=0;
          pCallgate^.Type1:=$0C;
          pCallgate^.System1:=0;
          pCallgate^.DPL:=3;
          pCallgate^.Present:=1;
          pCallgate^.Offset_16_31:=HiWord(DWORD(pvRing0FuncAddr));
          CallgateAddr[0]:=0;
          CallgateAddr[1]:=0;    
          CallgateAddr[2]:=(wGDTIndex shl 3) or 3;    
          asm    
            mov ebx, pulEAX    
            mov edi, pulEDX    
            mov ecx, ulECX    
            call dword ptr [CallgateAddr]    
          end;    
          ZeroMemory(pGDTDescriptor, 8);    
          CallRing0:=1;
          exit;
        end;
      Inc(pGDTDescriptor);
    end;    
    CallRing0:=0;
end;

end.
 

Это сообщение отредактировал(а) jungle - 26.6.2006, 11:44
PM MAIL WWW   Вверх
Romikgy
Дата 26.6.2006, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(jungle @  26.6.2006,  10:39 Найти цитируемый пост)
 исключение "ошибка доступа... Запись данных по адресу".

Это где?
И я не понял , ты делаешь прогу не под 98, а запускаешь под 98?

Добавлено @ 12:34 
И вопрос который меня мучает в этой теме :
НА КОЙ ТЕБЕ ПОД 98 НУЖНО НУЛЕВОЕ КОЛЬЦО?????

Имхо в 98 проблем с асмом нет, нулевое кольцо нужно для планки виндов НТ 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
jungle
Дата 26.6.2006, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аппаратный кодер



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.1.2006
Где: Беларусь

Репутация: нет
Всего: нет



Romikgy

Исходный код компилируется отлично. Как самый простейший пример – вызов функции CallRing0 я передаю в обработчике нажатия кнопки. Так вот после нажатия кнопки вываливается ошибка «Access violation at address XXXXX in module Project1.exe.Write of address XXXXX»

Нулевое кольцо под Windows 98 мне нужно для чтения привилегированных MSR-регистров процессора, в частности, для вызова инструкции rdmsr. Конечно, это цивилизованно делается через vxd-драйвер, который ещё нужно грамотно написать, но, увы, нет желания постигать устаревшую «грамоту».
 
PM MAIL WWW   Вверх
Romikgy
Дата 26.6.2006, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



jungle, покажи как используешь 
Цитата(jungle @  26.6.2006,  12:37 Найти цитируемый пост)
функции CallRing0 я передаю в обработчике нажатия кнопки

 smile 
Я дома проверю на 98 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
jungle
Дата 26.6.2006, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аппаратный кодер



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.1.2006
Где: Беларусь

Репутация: нет
Всего: нет



Romikgy

Испоьзую очень просто: CallRing0(@Ring0ReadMSR,$10,0,0);

MSR $00000010 - счетчик тактов процессора TSC.

Я б Delphi на ту машину с Win98 поставил бы да  в отладчике прозвонил бы, да вот места на харде нет.
 
PM MAIL WWW   Вверх
Romikgy
Дата 26.6.2006, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(jungle @  26.6.2006,  14:14 Найти цитируемый пост)
Ring0ReadMSR

какой структуры? 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
jungle
Дата 26.6.2006, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аппаратный кодер



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.1.2006
Где: Беларусь

Репутация: нет
Всего: нет



Ring0ReadMSR - это процедура чтения MSR регистра, адрес которой должен передаваться в функцию CallRing0 для выполнения Ring0ReadMSR в нулевом кольце. 
PM MAIL WWW   Вверх
Romikgy
Дата 26.6.2006, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Что должно быть после выполнения этой функции? 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
jungle
Дата 26.6.2006, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аппаратный кодер



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.1.2006
Где: Беларусь

Репутация: нет
Всего: нет



Число, которое, увеличивается при каждом повторном считывании TSC регистра (адрес $10).

Добавлено @ 16:49 
Хотя не принципиально, какая функция должна быть выполнена в нулевом кольце. Можно, например, написать функцию чтения портов или любую другую и передать ее адрес в функцию CallRing0 в качестве первого параметра. Просто процедура чтения MSR регистров Ring0ReadMSR как раз та, которая мне нужна. 
PM MAIL WWW   Вверх
Damarus
Дата 26.6.2006, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 671
Регистрация: 6.5.2006

Репутация: нет
Всего: 29



Я конечно не очень разбираюсь в Delphi, но моё мнение: структуры TGDT_DESCRIPTOR, TCALLGATE_DESCRIPTOR, TGDTR описаны не верно. 
PM MAIL ICQ Jabber   Вверх
Romikgy
Дата 26.6.2006, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Damarus @  26.6.2006,  17:49 Найти цитируемый пост)
Я конечно не очень разбираюсь в Delphi, но моё мнение: структуры TGDT_DESCRIPTOR, TCALLGATE_DESCRIPTOR, TGDTR описаны не верно.  

хмммм.....
jungle, тогда хедерный файл в студию, а то в твоем архиве оба сишных, по внутреностям 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Damarus
Дата 26.6.2006, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 671
Регистрация: 6.5.2006

Репутация: нет
Всего: 29



Romikgy, думаю хедерный файл не поможет. Мне кожется они и в нём описаны не верно. Моё мнение основано на этом:

IA-32 Intel® Architecture Software Developer’s Manual Volume 3:
System Programming Guide

Цитата

2.4. MEMORY-MANAGEMENT REGISTERS

The processor provides four memory-management registers (GDTR, LDTR, IDTR, and TR)
that specify the locations of the data structures which control segmented memory management
(see Figure 2-4). Special instructions are provided for loading and storing these registers.

System Table Registers

Код

      47                        16 15                 0
      ---------------------------- --------------------
GDTR | 32-bit Linear Base Address | 16-Bit Table Limit |
      ---------------------------- --------------------
IDTR | 32-bit Linear Base Address | 16-Bit Table Limit |
      ---------------------------- --------------------



Цитата

4.8.3. Call Gates

Call gates facilitate controlled transfers of program control between different privilege levels.
They are typically used only in operating systems or executives that use the privilege-level
protection mechanism. Call gates are also useful for transferring program control between 16-bit
and 32-bit code segments, as described in Section 17.4., “Transferring Control Among Mixed-
Size Code Segments”.

Figure 4-7 shows the format of a call-gate descriptor. A call-gate descriptor may reside in the
GDT or in an LDT, but not in the interrupt descriptor table (IDT). It performs six functions:

  • It specifies the code segment to be accessed.
  • It defines an entry point for a procedure in the specified code segment.
  • It specifies the privilege level required for a caller trying to access the procedure.

Код

                               14
 31                     16  15  13  12 11            8 7    6    5 4      0
 ------------------------- --- --- --- --------------- ----------- --------
|                         |   | D |   |               |           |        |
| Offset in Segment 31:16 | P | P | 0 |      Type     | 0   0   0 | Param. |
|                         |   | L |   | 1 | 1 | 0 | 0 |           | Count  |
 ------------------------- --- --- --- --------------- ----------- --------

 31                     16 15                                             0
 ------------------------- --- --- --- --------------- ----------- --------
|                         |                                                |
|    Segment Selector     |         Offset in Segment 15:00                |
|                         |                                                |
 ------------------------- --- --- --- --------------- ----------- --------
        DPL Descriptor Privilege Level
        P   Gate Valid


  • If a stack switch occurs, it specifies the number of optional parameters to be copied
    between stacks.
  • It defines the size of values to be pushed onto the target stack: 16-bit gates force 16-bit
    pushes and 32-bit gates force 32-bit pushes.
  • It specifies whether the call-gate descriptor is valid.

The segment selector field in a call gate specifies the code segment to be accessed. The offset
field specifies the entry point in the code segment. This entry point is generally to the first
instruction of a specific procedure. The DPL field indicates the privilege level of the call gate,
which in turn is the privilege level required to access the selected procedure through the gate.
The P flag indicates whether the call-gate descriptor is valid. (The presence of the code segment
to which the gate points is indicated by the P flag in the code segment’s descriptor.) The parameter
count field indicates the number of parameters to copy from the calling procedures stack to
the new stack if a stack switch occurs (see Section 4.8.5., “Stack Switching”). The parameter
count specifies the number of words for 16-bit call gates and doublewords for 32-bit call gates.
 
PM MAIL ICQ Jabber   Вверх
jungle
Дата 27.6.2006, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аппаратный кодер



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.1.2006
Где: Беларусь

Репутация: нет
Всего: нет



Romikgy

Вот хедер:

Код

#ifndef __MSR_9X_H__
#define __MSR_9X_H__

#include <windows.h>

int CallRing0(PVOID pvRing0FuncAddr,ULONG ulECX,ULONG* ulEAX,ULONG* ulEDX);
void Ring0ReadMSR();
void Ring0WriteMSR();

#pragma pack(1)

struct GDT_DESCRIPTOR
{
    WORD Limit_0_15;
    WORD Base_0_15;
    BYTE Base_16_23;
    BYTE Type         : 4;
    BYTE System       : 1;
    BYTE DPL          : 2;
    BYTE Present      : 1;
    BYTE Limit_16_19  : 4;
    BYTE Available    : 1;
    BYTE Reserved     : 1;
    BYTE D_B          : 1;
    BYTE Granularity  : 1;
    BYTE Base_24_31;
};

struct CALLGATE_DESCRIPTOR
{
    WORD Offset_0_15;
    WORD Selector;
    WORD ParamCount   : 5;
    WORD Unused       : 3;
    WORD Type         : 4;
    WORD System       : 1;
    WORD DPL          : 2;
    WORD Present      : 1;
    WORD Offset_16_31;
};

struct GDTR
{
    WORD wGDTLimit;
    DWORD dwGDTBase;
};

#pragma pack()

#endif // __MSR_9X_H__
 
PM MAIL WWW   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1040 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.