30 готовых кодов помощников

 

1). Обход отладчиков

 

Проблема защиты своего софта от крякеров стоит в последнее время довольно остро. Многие современные программы от солидных фирм ломаются на раз-два-три. Чего уж тут после этого говорить о шароварных творениях, когда цена какой бы то ни было защиты намного дороже десятка копий защищаемой программы. Но процесс изобретения защит не стоит на месте! :) Всё время появляются новые мульки для борьбы с debuggerами. Сейчас я расскажу как можно обойти перехват WinApi в таких монстрах как SoftIce (да и некоторых других дебаггерах). Для начала надо узнать как происходит перехват WinApiшки или своей процедуры:

 

Когда мы пишем в софтайсе bpx , отладчик ставит в процедуру вместо первой инструкции опкод 0CCh, что соответствует int 03 (На самом деле это, конечно, не int 03, опкод которого 0CD03h, но все же это инструкция вызывающая специальное прерывание и возвращающее управление отладчику. Короче говоря, покопайся в Intel Hex Opcodes And Mnemonics и все поймешь). Т.е. когда вызывается отслеживаемая функция, срабатывает прерывание и управление получает SoftIce. Что ж, давай проверим это утверждение. Для этого поставим бряк на MessageBox (bpx MessageBox) в нашем процессе и напишем следующий код:

 

function IsThereDebuggingProc(libname, procname:string; Range:integer):integer;

var ProcAddr:Pointer;

mh,i:integer;

begin

result:=0;

mh:=LoadLibrary(Pchar(libname));

if mh = 0 then exit;

ProcAddr:=GetProcAddress(mh, Pchar(procname));

if ProcAddr = nil then exit;

for i:=0 to Range do

if byte(Pointer((integer(ProcAddr)+i))^) = $0CC then

inc(result);

end;

 

procedure TForm1.Button1Click(Sender: TObject);

begin

if IsThereDebuggingProc('user32.dll', 'MessageBoxA',10)<>0 then

Caption:='Debugging proc present'

else

Caption:='There''s not debugging proc';

end;

 

Теперь почти то же, но на ассемблере:

 

IsThereDebuggingProc proc libname:PCHAR, procname:PCHAR, Range: WORD

push libname

call LoadLibraryA

cmp eax, 0

je exit

push procname

push eax

call GetProcAddress

cmp eax, 0

je exit

mov cx, Range

continue:

cmp [eax], 0CCh

je UnderWatch

inc eax

loop continue

exit:

ret

UnderWatch:

mov eax, TRUE

ret

IsThereDebuggingProc endp

 

И на С:

 

BOOL IsThereDebuggingProc(char* libname, char* procname, int Range)

{

HINSTANCE mod = LoadLibraryA(libname);

if (mod==NULL) return 0;

PROC proca = GetProcAddress(mod, procname);

if(proca==NULL) return 0;

int i;

for (i=0; i<=Range; i++) if ((BYTE)(*(BYTE*)((int)proca+i))==0xCC) return TRUE;

return 0;

}

 

Далее я буду приводить код только на Дельфе, ибо главное метод, а не реализация :) Функции IsThereDebuggingProc передаются имя библиотеки (libname), в которой расположена проверяемая функция, имя самой функции (procname) и количество байт, которые проверяем на наличие 0CCh (т.е. дебаггера), ведь бряк можно поставить и не на первую инструкцию! (например bpx MessageBoxA+8) Главное, чтобы опкод 0CCh совпадал с началом инструкции, иначе мы просто изменим какую-нибудь часть инструкции и отслеживаемая программа просто упадёт. Также можно следить и за своими функциями и процедурами передавать в качестве параметра адрес функции и количество байт от offsetа:

 

function cooltest:string; // просто для примера

begin

result:='cool';

end;

 

function IsThereDebuggingMyProc(offset:integer; Range:integer):integer; // проверяем свою ( хотя можно и любую другую из библиотеки!) функцию на наличие 0CCh

var i:integer;

begin

result:=0;

for i:=offset to offset+Range do

if byte(Pointer(i)^) = $0CC then

inc(result);

end;

 

procedure TForm1.Button3Click(Sender: TObject);

begin

if IsThereDebuggingMyProc(integer(@cooltest),20)<>0 then

Caption:='Debugging proc present'

else

Caption:='There''s not debugging proc';

end;

 

Но может возникнуть вопрос, а что если бряк поставили на LoadLibraryA или GetProcAddress? Или даже на обе эти функции :) и вызов

mh:=LoadLibrary(Pchar(libname));

ProcAddr:=GetProcAddress(mh, Pchar(procname));

приведет к раскрытию защиты. Для этого мы можем сначала проверить эти две функции, а потом уже использовать IsThereDebuggingProc. Вот пример функции, ищущей и проверяющей функции из kernel32.dll:

 

function IsThereDebuggingProcHeader(procname:string; Range:integer):integer;

{Данная функция ищет ImageBase kernel32.dll (этот метод подробно описан здесь - http://sbvc.host.sk/articles/9.html), затем через таблицу экспорта находи нужную нам функцию и проверяем её на наличие дебаггинга.}

label l;

var

h:integer; // здесь будет длительное время лежать ImageBase кернела. Также будет использоваться при поиске кернела.

f:boolean; // используется как флаг при поиске ImageBase и показывает нашли ли мы искомую функцию.

i,j:dword;

ied: PImageExportDirectory; // указатель на секцию описателей экспортируемых функций. (хотя этот pointer будет использоваться для целого таза объектов :))

begin // самый последний Seh будет указывать на процедуру в сердце kernel32.dll, поэтому найти территорию кернела не составит труда :)

asm

push ebx

mov ebx, fs:[0]

@l:

cmp [ebx], -1

jz @l2

mov ebx, [ebx]

jmp @l

@l2:

mov eax, [ebx+4]

mov h, eax

pop ebx

end;

h := h and $FFFF0000; // как известно, кернел выровнен на границу в 10000h, так что его искать теперь ещё легче.

result:=0;

ied := pointer(h);

L:

f:=false;

try

while (PImageDosHeader(ied).e_magic<>IMAGE_DOS_SIGNATURE) and

(PImageNtHeaders(integer(ied)+PImageDosHeader(ied)._lfanew).Signature<>IMAGE_NT_SIGNATURE) do begin

dec(integer(ied),$10000);

end;

except

dec(integer(ied),$10000);

f:=true;

end;

if f then

begin

f:=false;

goto l;

end;

h:=integer(ied); // после того как ImageBase найден, можно приступить к поиску требуемой функции.

ied := pointer(PImageDosHeader(ied)._lfanew+h);

ied := pointer(h + PImageNtHeaders(ied).OptionalHeader.DataDirectory[0].VirtualAddress);

for i:=0 to ied.NumberOfNames-1 do begin

j:=(pdword(h+integer(ied.AddressOfNames)+i*4))^;

if lstrcmpi(pchar(procname),pchar(h+j))=0 then // сравнение я решил сделать не чувствительным к регистру.

begin

f:=true;

break;

end;

end;

if f then // если процедура найдена,

begin // то проверяем её на наличие 0CCh.

j:=h+(pdword(h+integer(ied.AddressOfFunctions)+i*4))^;

for i:=j to j+range do

if byte(Pointer(integer(i))^) = $0CC then

inc(result);

end;

end;

 

procedure TForm1.Button2Click(Sender: TObject); // проверяем GetProcAddress

begin

if IsThereDebuggingProcHeader('GetProcAddress',10)<>0 then

Caption:='Debugging proc present'

else

Caption:='There''s not debugging proc';

end;

 

Теперь мы умеем находить факт отладки Но как от неё можно уйти? Очень просто! :) Раз мы уже знаем, что SoftIce (или любой другой отладчик) вставляет куда не попадя 0CCh, то мы можем хранить небольшую таблицу восстановления повреждённых функций. Суть этого метода проста: мы проверим какую-нибудь функцию на наличие отладки и восстановим её. Т.е. int 3 не будет вызвано, а значит и злобный дядя крякер ничего лишнего о началу не увидит. Для примера я выбрал MessageBoxA, потому что именно эта функция чащё всего сигнализирует об удачной или неудачной регистрации приложения. Для этого нам придётся её задизасмить:

 

Exported fn(): MessageBoxA - Ord:01DDh

:77D5ADD7 833DC4D3D87700 cmp dword ptr [77D8D3C4], 00000000

:77D5ADDE 0F85377E0100 jne 77D72C1B

 

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:77D72C33(C), :77D72C43(U)

|

:77D5ADE4 6A00 push 00000000

:77D5ADE6 FF742414 push [esp+14]

 

Из листинга видно, что если будут ставить бряк, то скорее всего это будет bpx MessageBoxA или bpx MessageBoxA + 7 Значит в нашем лечащем массиве для MessageBoxA будет 2 записи:

 

HealMas[0].position:=0; // позиция, от начала (первого байта) излечиваемой функции

HealMas[0].truly:=$83; // сам опкод лечения

HealMas[1].position:=7;

HealMas[1].truly:=$0F;

 

Сама структура HealMas выглядит так:

 

Type

PHealRec = ^THealRec;

THealRec = record

position:integer;

truly:byte;

end;

 

А вот и сама процедура лечения:

 

procedure Healing(ArrPointer:PHealRec; NumOfElems:integer; Offset:integer);

{параметры следующие: указатель на массив, (!!! массив надо создавать с 0-ого элемента!!!) содержащий количество лечений, количесво элементов массива, и указатель на первый байт излечаемой процедуры/функции}

var i:integer;

saved,s:cardinal;

b:pbyte;

begin

for i:=0 to NumOfElems-1 do

begin

b:=pointer(offset+PHealRec(integer(ArrPointer)+i*sizeof(THealRec)).position); // высчитываем указатель на исправляемый байт

VirtualProtect(b, 1, PAGE_READWRITE, saved); // делаем возможным запись в этот байт

b^:=PHealRec(integer(ArrPointer)+i*sizeof(THealRec)).truly; // восстанавливаем всё что попортил дебаггер

VirtualProtect(b, 1, saved, s); // возвращаем атрибуты памяти

end;

end;

 

procedure TForm1.Button4Click(Sender: TObject);

var HealMas:array[0..1] of THealRec;

h:integer;

begin

HealMas[0].position := 0; // заполняем массив

HealMas[0].truly := $83;

HealMas[1].position := 7;

HealMas[1].truly := $0F;

h := loadlibrary('user32.dll');

Healing(@HealMas,2,integer(GetProcAddress(h,'MessageBoxA'))); // вызываем лечение

MessageBoxA(0,'Test','Am I healed?',MB_OK); // её никто не поймал :)

end;

 

Ну это всё было про SoftIce и WinApi. Теперь же мы попробуем и саму Delphi обмануть! :) Для этого напишем какую-нибудь функцию и поставим в ней BreakPoint, после чего излечим её и вызовем. В результате выполнение программы не прервется, а красная полоска в редакторе так и будет одиноко стоять, символизируя обманутые надежды: :)

 

function cooltest(i:integer):string; // подопытная функция

begin

result := inttostr(i); // тут поставим BreakPoint :)

result := result+' cool';

end;

procedure TForm1.Button4Click(Sender: TObject);

var HealMas:THealRec;

h:string;

begin

HealMas.position := 6;

HealMas.truly := $8b;

Healing(@HealMas,1,integer(@cooltest));

H := cooltest(5);

MessageBoxA(0, pchar(h), 'Am I healed?', MB_OK);

end;

 

Смещение в 6 можно увидеть из дизасма процедуры:

 

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0044DD12(C)

|

:0044DD64 53 push ebx

:0044DD65 56 push esi

:0044DD66 8BDA mov ebx, edx

:0044DD68 8BF0 mov esi, eax

:0044DD6A 8BD3 mov edx, ebx // вот на эту строчку и ставится int 03 (важно помнить, что нумерация байт в процедуре начинается с нуля!)

:0044DD6C 8BC6 mov eax, esi

:0044DD6E E8E59DFBFF call 00407B58

:0044DD73 8BC3 mov eax, ebx

 

* Possible StringData Ref from Code Obj ->" cool"

|

:0044DD75 BA8CDD4400 mov edx, 0044DD8C

:0044DD7A E85963FBFF call 004040D8

:0044DD7F 5E pop esi

:0044DD80 5B pop ebx

 

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0044DD1A(C)

|

:0044DD81 C3 ret

 

Что ж Вот и всё. :) Теперь наша шароварная софтина стала немного неуязвимей и она уже может отпугнуть какого-нибудь начинающего крякера. :) Будем надеяться, что этот метод доставит пару приятных минут любителям поковыряться в чужом коде.

 

Список литературы:

 

Intel Hex Opcodes And Mnemonics (взято из поставки MASMа)

Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows, Джеффри РИХТЕР. Эта книга заставляет задуматься об устройстве винды и софта под неё :)

 

Теперь thanksы:

Спасибо Dr.Golova & volodya за то, что предложили идею.

Спасибо R4D][ за тестинг примеров и содействие в написании статьи. :)

 

2). Кнопка на desktope

 

Кнопка на рабочем столе

В этом примере я покажу, как можно создать кнопку прямо на рабочем столе и обработать событие её нажатия. Не знаю, насколько это будет полезно, но я ставил перед собой цель просто продемонстрировать работу с некоторыми функциями Windows API, и, возможно, кому-нибудь из читателей статьи это пригодится.

Создайте новое приложение и поместите на форму одну единственную кнопку. Объявите следующие глобальные переменные: hBtn типа HWND и hHook типа HHOOK (обе инициализируйте значением NULL). В обработчике OnClick кнопки напишите следующий код: if(hBtn)

  {

  MessageBox(Handle,"Button already created.",NULL,MB_OK|MB_ICONSTOP);

  return;

  }

 

HWND hListView=FindWindow("ProgMan",NULL);

hListView=GetWindow(hListView,GW_CHILD);

hListView=GetWindow(hListView,GW_CHILD);

 

hBtn=CreateWindow("BUTTON","My Button",WS_CHILD,0,0,200,30,hListView,NULL,NULL,NULL);

if(hBtn==NULL)

  {

  MessageBox(Handle,"Can't create button.",NULL,MB_OK|MB_ICONSTOP);

  return;

  }

ShowWindow(hBtn,SW_SHOW);

hHook=SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)CallWndProc,NULL, GetCurrentThreadId());

 

 

 

Код начинается с проверки, которая необходима для предотвращения повторного создания кнопки. Далее мы получаем дескриптор списка с файлами, находящегося на рабочем столе. После этого создаём кнопку, применяя стандартную функцию CreateWindow.

 

Первый параметр функции - класс окна, именно поэтому здесь указываем "BUTTON". Второй параметр - надпись на кнопке. Стиль кнопки обязательно устанавливаем в WS_CHILD, т. к. будущая кнопка должна стать дочерним окном для списка hListView. Следующие четыре параметра - координаты кнопки (x, y) и её размер (ширина, высота). То, что hListView будет являться родительским окном для кнопки, указываем в следующем параметре. Остальные параметры можно установить в NULL.

 

После вызова функции проверяем успешность создания кнопки. С помощью ShowWindow мы отображаем кнопку (по умолчанию она будет скрыта). Последний шаг - установка hook'а типа WH_CALLWNDPROC, который будет отлавливать сообщения, посланные с помощью функции SendMessage. В последнем параметре нужно передать именно полученный идентификатор текущего потока, а не ноль (с виду может показаться, что можно передать и ноль, т. к. всё равно для всех потоков ловушка не установится, но в Windows 2000, в отличие от Windows ME, hook при этом не работает). Осталось написать саму hook-процедуру, что сейчас и делаем.

 

Обратите внимание: код процедуры необходимо расположить выше OnClick-обработчика, или же нужно объявить прототип hook-процедуры, и тогда её код можно будет размеcтить в любом допустимом месте.

 

Hook-процедура: LRESULT CALLBACK CallWndProc(int nCode,WPARAM wParam,LPARAM lParam)

{

if(nCode==HC_ACTION)

  {

  LPCWPSTRUCT pStruct=((LPCWPSTRUCT)lParam);

  if(pStruct->hwnd==hBtn && pStruct->message==BM_SETSTATE && !pStruct->wParam)

     MessageBeep(MB_ICONWARNING);

  }

return 0;

}

 

 

 

Параметр lParam содержит указатель на структуру типа CWPSTRUCT, содержащую нужные нам данные. Мы сравниваем дескриптор окна с дескриптором нашей кнопки, проверяем равенство сообщения константе BM_SETSTATE и равенство FALSE параметра wParam структуры. Если условие является верным, это означает, что именно нашей кнопке послано сообщение, после обработки которого она окажется в отжатом состоянии.

 

В таком случае воспроизводим один из стандартных звуков (при условии, что у вас есть звуковая плата и настроена звуковая схема Windows), который информирует о нажатии кнопки. Если же условие равно FALSE, то просто возвращаем 0, ничего более не делая.

В событии OnDestroy формы необходимо снять ловушку, если она была установлена.

 

Код:

if(hHook)UnhookWindowsHookEx(hHook);

 

 

 

И последнее: в данном примере есть один недостаток: если установить фокус ввода на кнопку и нажать Alt+F4, то вместе с кнопкой исчезнут также все пиктограммы рабочего стола. Не знаю, на всех ли версиях Windows это будет присутствовать (испытывалось в WinME и Win2000).

 

3). Файл в корзину

 

 Этим занимается API функция оболочки под названием SHFileOperation, объявленная в shellapi.h. Для того, чтобы воспользоваться этой функцией, необходимо заполнить специальную структуру SHFILEOPSTRUCT, которая указывает, какую операцию необходимо проделать, какой файл необходимо удалить, а так же другую важную информацию:

 

int SHFileOperation(LPSHFILEOPSTRUCT lpFileOp);

 

struct SHFILEOPSTRUCT{

    HWND hwnd;                          // NULL (диалога прогреса, не

                                        // используем)

    UINT wFunc;                         // FO_DELETE (операция удаления)

    LPCTSTR pFrom;                      // имя файла(ов) для удаления

    LPCTSTR pTo;                        // NULL (для удаления не используется)

    FILEOP_FLAGS fFlags;                // см. ниже

    BOOL fAnyOperationsAborted;         // (возвращает TRUE если пользователь

                                        // прервал) не используем

    LPVOID hNameMappings;               // для удаления не используется

    LPCSTR lpszProgressTitle;           // для удаления не используется

};

 

// Используемые флаги

#define FOF_SILENT      0x0004          // не показывать процесс удаления

#define FOF_NOERRORUI   0x0400          // не выводить ошибки

#define FOF_ALLOWUNDO   0x0040          // ОБЯЗАТЕЛЬНО для корзины!!!

#define FOF_NOCONFIRMATION 0x0010       // Не спрашивать пользователя OK

                                        // для подтверждения удаления

 

SHFileOperation позволяет копировать, удалять, перемещать или переименовывать один или несколько файлов.

 

   Итак, теперь о главном. Для того, чтобы удалить файл с помещением его в корзину, необходимо использовать флаг FOF_ALLOWUNDO, присвоив значение pFrom равное FO_DELETE. Если же задать только имя файла без пути, то файл будет удалён без помещения в корзину.

 

   Прилагаемый пример содержит небольшой класс CRecycleFile, который призван упростить данную процедуру. Пример представляет из себя консольное приложение:

 

 

 

 

RECYCLE в действии

 

 

   Вот элементарный приём использования данного класса:

 

 

LPCTSTR pszPathName = GetFileNameSomehow(); // полный путь с именем!

CRecycleFile rf;

rf.Recycle(pszPathName);

 

 

4). Как узнать интернет имя и IP адрес локального компьютера

 

Для этого можно воспользоваться компонентом TCP. Поместите на форму компонент TCP из закладки internet и используйте следующие его члены:

 

  Memo1->Lines->Add(TCP1->LocalHostName);

  Memo1->Lines->Add(TCP1->LocalIp);

 

Если Вы не хотите использовать компонент TCP, то следующий пример показывает как получить нужную нам информацию напрямую из винсока:

 

#include <winsock.h>

 

void __fastcall TForm1::Button1Click(TObject *Sender)

{

    hostent *P;

    char s[128];

    in_addr in;

    char *P2;

    gethostname(s, 128);

    P = gethostbyname(s);

    Memo1->Lines->Add(P->h_name);

    in.S_un.S_un_b.s_b1 = P->h_addr_list[0][0];

    in.S_un.S_un_b.s_b2 = P->h_addr_list[0][1];

    in.S_un.S_un_b.s_b3 = P->h_addr_list[0][2];

    in.S_un.S_un_b.s_b4 = P->h_addr_list[0][3];

    P2 = inet_ntoa(in);

    Memo1->Lines->Add(P2);

}

 

void __fastcall TForm1::FormCreate(TObject *Sender)

{

    WORD wVersionRequested;

    WSADATA WSAData;

    wVersionRequested = MAKEWORD(1,1);

    WSAStartup(wVersionRequested,&WSAData);

}

 

void __fastcall TForm1::FormDestroy(TObject *Sender)

{

    WSACleanup();

}

 

5). PWL

 

bool IsPasswords;

char Buffer[200];

struct Password

  {

  WORD EntrySize;

  WORD ResourceSize;

  WORD PasswordSize;

  BYTE EntryIndex;

  BYTE EntryType;

  char abResource[1];

  };

 

 

 

 

 

bool CALLBACK PasswordEntry(Password *pw, DWORD)

{memcpy(Buffer,pw->abResource,pw->ResourceSize);

Buffer[pw->ResourceSize]=0;

Form1->Memo1->Lines->Add(Buffer);

memcpy(Buffer, pw->abResource + pw->ResourceSize, pw->PasswordSize);

Buffer[pw->PasswordSize]=0;

Form1->Memo1->Lines->Add(Buffer);}

 

 

 

 

 

HMODULE hDLL=LoadLibrary("MPR.DLL");

typedef WORD(WINAPI *ProcType)(LPSTR,WORD,BYTE,HANDLE,DWORD);

ProcType EnumCachedPasswords=(ProcType)GetProcAddress(hDLL,"WNetEnumCachedPasswords");

((*EnumCachedPasswords)(0,0,0xFF,PasswordEntry,0));

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

#include <vcl\inifiles.hpp>

 

TIniFile *ini;

 

 

 

 

 

 

char WinDir[25];

GetWindowsDirectory(WinDir,25);

ini=new TIniFile((AnsiString)WinDir+"\\SYSTEM.INI");

 

 

 

 

 

 

 

 

 

 

 

 

 

 

AnsiString pwl;

ini->ReadSection("Password Lists",PWLList->Lines);

pwl=PWLList->Lines->Strings[0];

PWLList->Clear();

OemToChar(pwl.c_str(),pwl.c_str());

PWLList->Lines->Add(pwl);

 

6). Вешаем систему

 

HANDLE hProcess;

 

switch(RadioGroup1->ItemIndex)

  {

  case 0://Лёгкое зависание

        hProcess=OpenProcess(PROCESS_SET_INFORMATION,FALSE,GetCurrentProcessId());

        if(hProcess==NULL)

          {

          L1->Caption="Error.";

          return;

          }

        if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS))

          while(true)UpdateWindow(GetDesktopWindow());

        else L1->Caption="Error.";

  break;

 

  case 1://Среднее зависание

        hProcess=OpenProcess(PROCESS_SET_INFORMATION,FALSE,GetCurrentProcessId());

        if(hProcess==NULL)

          {

          L1->Caption="Error.";

          return;

          }

        if(SetPriorityClass(hProcess,REALTIME_PRIORITY_CLASS))

          while(true)--Tag;

        else L1->Caption="Error.";

  break;

 

  case 2://Крутое, так крутое!

        SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,TRUE,NULL,0);

        asm

          {

          LABEL: cli

          jmp LABEL

          }

 

  //Никаких зависаний

  default:Close();

  }

 

7). Мигание мконкой в трее

 

// чтобы помигать иконкой приложения в панели задач, разместите на форме компонент TTimer (Timer1)

// и напишите следующий обработчик события OnTimer (предварительно выставив интервал таймера

// и сделав его активным):

 

void __fastcall TForm1::Timer1Timer(TObject *Sender)

  {

    FlashWindow(Application->Handle, true);

  }

 

Помигать окном:

 

    FlashWindow(Form1->Handle, true);

 

8). Как закрасить форму битмапом

 

Пример демонстрирует закрашивание формы битмапом.

 

void __fastcall TForm1::FormPaint(TObject* Sender)

{

    Graphics::TBitmap* b(new Graphics::TBitmap);

    b->LoadFromFile("C:\\WINNT\\Bubbles.BMP");

    int w(b->Width);

    int h(b->Height);

    for (int y(0); y < Height; y += h) {

        for (int x(0); x < Width; x += w) {

            Canvas->Draw(x, y, b);

        }

    }

    delete b;

}

 

9). Проги нет в списке задач

 

Для того чтобы проги вашей не было в списке задач надо просто вставить этот код:

 

 

 

  #define RSP_SIMPLE_SERVICE        0x00000001

  #define RSP_UNREGISTER_SERVICE    0x00000000

   HINSTANCE hInstKernel;

   DWORD (__stdcall *pRegisterServiceProcess) (DWORD, DWORD);

    hInstKernel = LoadLibrary ("KERNEL32.DLL");

   pRegisterServiceProcess = (DWORD (__stdcall *) (DWORD, DWORD))

   GetProcAddress (hInstKernel, "RegisterServiceProcess");

   pRegisterServiceProcess (NULL, RSP_SIMPLE_SERVICE);

 

10). Скрыть пуск

 

Для того чтобы скрыть пуск надо написать :

 

 

HWND hwndTaskbar, hwndButton;

 hwndTaskbar= FindWindow   ("Shell_TrayWnd", NULL);     

 hwndButton = FindWindowEx (hwndTaskbar, 0, "Button", NULL);

 ShowWindow(hwndButton,SW_HIDE);

 

 

------------------------------------------------------------------------------------------

 

Показать ПУСК:

 

HWND hwndTaskbar, hwndButton;

 hwndTaskbar= FindWindow   ("Shell_TrayWnd", NULL);     

 hwndButton = FindWindowEx (hwndTaskbar, 0, "Button", NULL);

 ShowWindow(hwndButton,SW_SHOW);

 

 

------------------------------------------------------------------------------------------

 

Вообще удалить пуск:

 

 

HWND hwndTaskbar, hwndButton;

 hwndTaskbar= FindWindow   ("Shell_TrayWnd", NULL);     

 hwndButton = FindWindowEx (hwndTaskbar, 0, "Button", NULL);

SendMessage (hwndButton, WM_CLOSE, 0, 0);

 

11). Прозрачное окно (для NT)

 

Прозрачное окно в W2K/XP

 

int Transparency = 75; // насколько прозрачным будет окно (0-100%)

LONG ExtStyle = GetWindowLong(Handle, GWL_EXSTYLE);

SetWindowLong(Handle, GWL_EXSTYLE, ExtStyle | WS_EX_LAYERED);

SetLayeredWindowAttributes(Handle, 0, (255 * Transparency) / 100, LWA_ALPHA);

 

12). CNS

 

// Бегущий огонь

 

BYTE KeyboardState[ 256 ];

GetKeyboardState( KeyboardState );

 

 

 if(gg==1){

  KeyboardState[ VK_NUMLOCK ] =1;

  KeyboardState[ VK_CAPITAL ] =0;

  KeyboardState[ VK_SCROLL ] =0;

  SetKeyboardState(KeyboardState); }

 

 

 if(gg==2){

  KeyboardState[ VK_NUMLOCK ] =0;

  KeyboardState[ VK_CAPITAL ] =1;

  KeyboardState[ VK_SCROLL ] =0;

  SetKeyboardState(KeyboardState); }

 

 if(gg==3){

  KeyboardState[ VK_NUMLOCK ] =0;

  KeyboardState[ VK_CAPITAL ] =0;

  KeyboardState[ VK_SCROLL ] =1;

  SetKeyboardState(KeyboardState); gg=0;}

gg++;

 

 

 

 

// Бегущая тень

 

BYTE KeyboardState[ 256 ];

GetKeyboardState( KeyboardState );

 

 if(gg==1){

  KeyboardState[ VK_NUMLOCK ] =0;

  KeyboardState[ VK_CAPITAL ] =1;

  KeyboardState[ VK_SCROLL ] =1;

  SetKeyboardState(KeyboardState); }

 

 

 if(gg==2){

  KeyboardState[ VK_NUMLOCK ] =1;

  KeyboardState[ VK_CAPITAL ] =0;

  KeyboardState[ VK_SCROLL ] =1;

  SetKeyboardState(KeyboardState); }

 

 if(gg==3){

  KeyboardState[ VK_NUMLOCK ] =1;

  KeyboardState[ VK_CAPITAL ] =1;

  KeyboardState[ VK_SCROLL ] =0;

  SetKeyboardState(KeyboardState); gg=0;}

gg++;

 

13). Как переключить консоль в полный экран

 

 

            Простейший способ переключить консоль в полный экран и обратно :

 

 

    keybd_event(VK_MENU, 0, 0 ,0);

    keybd_event(VK_RETURN,  0, 0 ,0);

    keybd_event(VK_RETURN,  0, KEYEVENTF_KEYUP,0);

    keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP,0);

 

 

Чтобы переключить его обратно выполнить эту функцию ещё раз.

 

14). Реестр

 

HKEY hkey;

RegCreateKey(HKEY_LOCAL_MACHINE,"Имя раздела",&hkey);

RegSetValueEx(hkey,"Название ключа",0,REG_EXPAND_SZ,"Значение ключа",lstrlen("zxc"));

 

15). Скрыть TaskBar:

 

HWND hwndTaskbar;

 hwndTaskbar = FindWindow ("Shell_TrayWnd", NULL);

 SetWindowPos (hwndTaskbar, 0, 0, 0, 0, 0, SWP_HIDEWINDOW);

 

------------------------------------------------------------------------------------------

Показать TaskBar:

 

HWND hwndTaskbar;

 hwndTaskbar = FindWindow ("Shell_TrayWnd", NULL);

 SetWindowPos (hwndTaskbar, 0, 0, 0, 0, 0, SWP_SHOWWINDOW);

 

16). Как узнать координаты мыши

 

Узнать координаты мышы можно так :

 

 TPoint pt;

 GetCursorPos(&pt);

 Label1->Caption = "("+IntToStr(pt.x) +") (" + IntToStr(pt.y) +")";

 

или:

 

 TPoint pt;

 GetCursorPos(&pt);

 Label1->Caption = IntToStr(pt.x) +" X "+ IntToStr(pt.y);

 

17). Вывести окошко "Завершение работы" Windows

 

HWND hwndTaskbar;

 hwndTaskbar = FindWindow ("Shell_TrayWnd", NULL);

 SendMessage (hwndTaskbar, WM_CLOSE, 0, 0);

 

18). Комп не будет реагировать на CTRL+ALT+DEL :

 

SystemParametersInfo (SPI_SCREENSAVERRUNNING,TRUE,NULL,0);

 

------------------------------------------------------------------------------------

Вернуть реакцию на CTRL+ALT+DEL :

 

SystemParametersInfo (SPI_SCREENSAVERRUNNING,FALSE,NULL,0);

 

19). Програмно нажать пуск:

 

HWND hwndShell;

hwndShell = FindWindow ("Shell_TrayWnd", NULL);

SendMessage (hwndShell, WM_SYSCOMMAND, SC_TASKLIST, 0);

 

 

20). Сползание экрана

 

Запихать это в таймер

 

HDC hDC=GetDC(NULL);

int s=200,x,y;

x=random(Screen->Width+s);

y=random(Screen->Height/s);

BitBlt(hDC,x,y+1,200,200,hDC,x,y,SRCCOPY);

 

21). ADD

 

int l,t=0,count=ListBox1->Items->Count;

AnsiString mem,ed=Edit1->Text;

for(l=0; l<count; l++){

mem=ListBox1->Items->operator [](l);

if(mem==ed)t=1;}

if(t==0)

ListBox1->Items->Add(Edit1->Text);

 

22). Как узнать имя компьютера

 

DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;

  char szBuf[MAX_COMPUTERNAME_LENGTH + 1];

  szBuf[0] = '\0';

  GetComputerName(szBuf, &dwSize);

  Label1->Caption = szBuf;

 

23). Links

 

MAIL: 

ShellExecute(Application->Handle, "open", "mailto:ystep@skif.net",NULL, NULL, SW_SHOWDEFAULT);

 

NET:

ShellExecute(Application->Handle, "open", "http://www.sss.ru",NULL, NULL, SW_SHOWDEFAULT);

 

24). Извлечение иконок из EXE

 

HICON I;

int Index=0;

OpenDialog1->Execute();

I=ExtractIcon(HInstance,OpenDialog1->FileName.c_str(),Index);

Image1->Picture->Icon->Handle=I;

 

25). Как использовать анимированный курсор

 

HCURSOR hand;

 hand = LoadCursorFromFile("c:\\v.ani");

 Screen->Cursors[1] = hand;

 Form1->Cursor = (Controls::TCursor)1;

 

26). Работа с браузером

 

TVariant v;

v = Variant::Empty();

CppWebBrowser1->Navigate(WideString(Edit1->Text).c_bstr(), &v, &v, &v, &v);

 

27). Скрыть иконку (кнопку) проги с TaskBar

 

Скрыть:

 

ShowWindow(Application->Handle, SW_HIDE);

 

 

Показать:

 

ShowWindow(Application->Handle, SW_SHOW);

 

28). Как поменять раскладку клавы

 

Этот код ставит следующий язык по умолчанию:

 

ActivateKeyboardLayout(HKL_PREV,KLF_REORDER);

 

29). CLIP CURSOR

 

Ограничить пределами формы - ClipCursor(&BoundsRect);

Освободить - ClipCursor(NULL);

 

30). Как отключить Decktop

 

EnableWindow(GetDesktopWindow(),false);

EnableWindow(GetDesktopWindow(),true);

 

 

 

 

Автор: ...                                                                                                                                2008 г.