Bir Kiosk ve CreateDesktop macerası.. | Delphi Programming

Transkript

Bir Kiosk ve CreateDesktop macerası.. | Delphi Programming
Contact Me | Subscribe
D e l p h i
P r o g r a m m i n g
Search Keywords
There are only 10 types of people in the world: Those who understand binary, and those
who don’t.
Home
TObject.Create
Delphi
Hakkında
Ziyaretçi Defteri
Posted by Tuğrul HELVACI - Mayıs 20, 2009 Comments 17
Bir Kiosk ve CreateDesktop macerası..
Plugin WP FlashTime by horoscop 2009.org
requires Flash Player 8 or better currency
converter calculator.Plugin creat de horoscop |
horoscop saptamanal | horoscop zilic | horoscop
| play sonic games
Bu yazıma gecenin bu saatinde başladığıma göre büyük ihtimalle yarın işe geç kalacağım.
Ama tamamlandığında da bu konuyu 3 gündür makaleleştirememenin verdiği sıkıntıdan da
kurtulmuş olacağım. Sanırım bu kafi derecede haz verir bana.
Hayatının herhangi bir anında herhangi bir husus hakkında birşeyler karalamış olanlar bilirler ki,
bir şeyi biliyor olmak ile anlatabiliyor olmak cidden farklı. Bunlar farklı kaabiliyetler sanıyorum.
Ve yine yazmaya gönlü kaymış kişiler bilir ki; bazen bir konuyu layıkı ile anlatamama endişesi
“acaba hiç mi yazmasam” düşüncesine hayat verir. Bende böyle gitgeller yaşadım bu makale
için ama elimden geldiğince kendi üslubum gereği aklıma gelen tüm detaylara da inerek bir
cesaretle ya Allah diyip başlıyorum makaleye. Şimdiden okuyanların gözlerini ve zihinlerini
yoracağım için helallik diliyorum.
Aslında anlatacaklarım tam bir kiosk uygulaması değil elbette. Ancak bir ucundan dokunuyor.
Daha ziyade Unix türevli işletim sistemlerinin popüler KDE, Gnome gibi arayüzlerinde görmeye
alıştığımız multi-desktop meselesini anlatmaya çalışacağım. Pek çok kullanıcı bazen
muzurluk adına ve bazen de gerçekten işi gereği çoklu masaüstlerine ihtiyaç duyar. İşyerinde
çalışırken, başkalarından gizlemek istediği programları başka bir masaüstünde barındırmak
Etiketler
Absolute Abstract Classes ActionScript Algoritma
API
Bug Byte Arrays Class Reference CloseHandle
COM CreateDesktop CreateEvent CreateMutex
CreateProcess CreateRemoteThread CreateSemaphore
CreateToolHelp32SnapShot CreateWaitableTimer
DeleteCriticalSection delphi 2010 DTS EnterCriticalSection
EnumDesktopProc EnumDesktops Flash
Function
PDFmyURL.com
isteyen insanların sayısı gerçekten de az değildir. Hatta irili ufaklı pek çok uygulamada vardır
sevgili patron ve müdürlerin gözlerinden sizleri korumak için
Bazı yazılımlar ise, muzurluk adına değil de yapmaları icap eden iş gereği başka
masaüstlerinde çalışma ihtiyacı hissederler. Kiosk uygulamaları gibi. Bu uygulamalar genelde
topluma açık yerlerde herkesin kullanımına sunulduklarından işletim sistemine müdahalenin
mümkün mertebe sınırlandırılması gerekir. Bunun için en güzel çözümlerden bir tanesi
uygulamanın kendisine has bir masaüstünde çalışmasıdır. Böylelikle bilerek yada bilmeyerek
verilecek zararlar minimize edilmiş olur.
Tüm bu düşüncelerin ışığında, bir kaç gün evvel kendime ait bir masaüstü nasıl yaparım diye
oturdum araştırma yaptım. Başta herşey iyi gidiyordu. İstediğimi yapabilmiştim. İşletim
sistemi üzerinde bir masaüstü oluşturabilmiş, o masaüstüne geçebilmiş ve hatta uygulamamı
yalnız başına orada çalıştırmayı başarabilmiştim. Buraya kadar herşey gayet iyi idi. Ancak ne
oldu ise ondan sonra oldu
Programlama sanatına gönül vermiş insanların uzun
makaleleri okurken sıkıldıklarını, konudan uzaklaşma eğilimi gösterdiklerini gözlemledim
programlama hayatım boyunca. Bu sebeple, kodsal içeriklere başlayarak ilerlemeyi sizlerin
sıkılmaması adına tercih ediyorum.
Sizlere ilk bahsedeceğim API CreateDesktop API’si olacak: CreateDesktop API’si Win32
Programmers Referance’da aşağıdaki şekilde tanımlanmıştır.
1.
2.
3.
4.
5.
6.
7.
8.
HDESK CreateDesktop(
LPCTSTR lpszDesktop,
// name of the new desktop
LPCTSTR lpszDevice,
// reserved; must be NULL.
LPDEVMODE pDevMode,
// reserved; must be NULL
DWORD dwFlags,
// flags to control interaction
with other applications
DWORD dwDesiredAccess, // specifies access of returned
handle
LPSECURITY_ATTRIBUTES lpsa // specifies security
attributes of the desktop
);
Aynı API’nin Delphi’deki tanımı ise:
1.
2.
3.
function CreateDesktop(lpszDesktop, lpszDevice: PChar;
pDevmode: PDeviceMode; dwFlags: DWORD; dwDesiredAccess:
DWORD; lpsa: PSecurityAttributes): HDESK; stdcall;
şeklindedir. Adından anlaşılabileceği gibi bu fonksiyon yeni bir masaüstü oluşturmaktadır.
Fonksiyonumuzun birinci parametresi desktop’umuza vereceğimiz isimdir. İkinci ve üçüncü
paratemtelerin Nil(Null) olması gerektiği bildirilmektedir yardım dökümanında. dwFlags isimli
dördüncü parametre ise çalıştırılacak olan uygulamanın yeni desktopta diğer uygulamalar ile
nasıl bir işbirliği yapacağını belirtirmiş. Ancak bunu nasıl yapar, derinlerinde ne gibi ipuçları
EnumDesktopProc EnumDesktops Flash
Function
Pointer GetCurrentProcess
GetIconInfo GetKeyState
GetLastInputInfo GetProcessMemoryInfo GetStartupInfo
GetThreadContext GetTickCount GetTickCount64
Hacking Inheritance InitializeCriticalSection
Interface InterlockedCompareExchange
InterlockedDecrement InterlockedExchange
InterlockedExchangeAdd InterlockedIncrement
JavaScript LeaveCriticalSection Method Pointer
Module32First Module32Next MSSQL OpenDesktop
OpenEvent OpenMutex OpenSemaphore
OpenWaitableTimer Operator Overloading
Persistance
Pointer Procedure Pointer Process
Process32First Process32Next Query QueryInterface
QueryPerformanceCounter Queue ReleaseMutex
ReleaseSemaphore Reqursion ResetEvent ResumeThread
RTTI SetEvent SetProcessWorkingSetSize
SetThreadContext SetWaitableTimer Smilarity SORT SQL
SQL Server
Stream SuspendThread Sw itchDesktop
TDateTime TerminateProcess TerminateThread
Thread TInterfacedObject TValue Untyped
Parameters VirtualAllocEx VirtualFreeEx
WaitForSingleObject
WaitForMultipleObjects
Weaver WriteProcessMemory _AddRef _Release
WP Cumulus Flash tag cloud by Roy Tanck
requires Flash Player 9 or better.
Son Yorumlar
Yeni Veri Tipleri ve Operator Overloading için
Tuğrul HELVACI
Yeni Veri Tipleri ve Operator Overloading için
Zafer Çelenk
Delphi ve Google Maps API için Tuğrul
HELVACI
Delphi ve Google Maps API için ahmet
Ziyaretçi Defteri için Tuğrul HELVACI
PDFmyURL.com
vardır henüz bilmiyorum. Ancak yardım dosyasında denildiği kadarı ile dwFlags’ın alabileceği
değer ya sıfır olabilirmiş yada DF_ALLOWOTHERACCOUNTHOOK olabilirmiş. Biz bu
parametre için bu değeri kullanacağız. DF_ALLOWOTHERACCOUNTHOOK sabiti
Windows.pas’da 1 değeri ile ifade edilmiştir.
dwDesiredAccess isimli parametremiz ise yeni oluşturacağımız desktopumuzun
kaabiliyetlerini ifade edecek. Yine yardım dosyasında aşağıdaki değerlere sahip olabileceğini
gözlemleyebilirsiniz:
01.
02.
03.
04.
05.
06.
07.
08.
09.
DESKTOP_READOBJECTS = 1;
DESKTOP_CREATEWINDOW = 2;
DESKTOP_CREATEMENU = 4;
DESKTOP_HOOKCONTROL = 8;
DESKTOP_JOURNALRECORD = $10;
DESKTOP_JOURNALPLAYBACK = $20;
DESKTOP_ENUMERATE = $40;
DESKTOP_WRITEOBJECTS = 128;
DESKTOP_SWITCHDESKTOP = $100;
Bu parametrenin alabileceği değerler son derece mühim. Yeni oluşturacağınız desktop’un
yapabilecekleri bu parametrelerle belirleniyor. Biz desktopumuzun her türlü hakka sahip
olmasını isteyeceğiz bu uygulamamızda. O sebeple aşağıdaki gibi bir tanım yapacağız:
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
const
DESKTOP_ALL =
DESKTOP_READOBJECTS or
DESKTOP_CREATEWINDOW or
DESKTOP_CREATEMENU or
DESKTOP_HOOKCONTROL or
DESKTOP_JOURNALRECORD or
DESKTOP_JOURNALPLAYBACK or
DESKTOP_ENUMERATE or
DESKTOP_WRITEOBJECTS or
DESKTOP_SWITCHDESKTOP;
Son parametremiz ise işletim sisteminde tanımlı olan ve genellikle hep nil bıraktığımız güvenlik
parametresi. Bu parametre işletim sistemi güvenliği ile ilgili derin güvenlik bilgileri istiyor,
açıkçası bu hususta az bir bilgim var o yüzden sizlere bu parametrenin detaylarını
anlatamayacağım. Bu parametremizi de Nil(Null) olarak geçeceğiz. Tüm bu bilgilerin ışığında
artık desktop’umuzu oluşturan kodumuzu yazabiliriz:
1.
2.
3.
4.
5.
6.
7.
var
NewDesktop : HDESK;
begin
NewDesktop := CreateDesktop(PChar('NewDesktop'), nil, nil,
DF_ALLOWOTHERACCOUNTHOOK, DESKTOP_ALL, nil);
..
..
end;
Ziyaretçi Defteri için Tuğrul HELVACI
Son Yazılar
Yeni Veri Tipleri ve Operator Overloading
Interface Nedir, Nerelerde ve Neden Kullanırız ?
Derinlemesine Threading..(3)
SQL’de Benzerlik Algoritmaları…
Full Text Searching…
Kategoriler
Genel (4)
IDE (1)
İşletim Sistemi (7)
Programlama (43)
.Net (3)
C# (2)
Delphi (43)
Grafik (2)
Internet (4)
Veritabanı (3)
Win32 (6)
Takvim
Temmuz 2010
Pts Sal Çar Per Cum Cts Paz
1
2
3
4
PDFmyURL.com
Evet artık işletim sistemi üzerine yeni bir masaüstü daha açtık. Ama tabii ki henüz onu
göremiyoruz. Kaç tane masaüstümüz olduğunu da bilmiyoruz şu anda. Bazı arkadaşlarımın,
“Nasıl bilmiyoruz ? Bir tane vardı bir de biz oluşturduk etti iki..” dediğinizi duyar gibiyim
Yok yok iki tane değil
İşletim sistemimizde mevcut birden fazla masaüstü var. Arzu ederseniz daha fazla ilerlemeden
önce bu söylemimizin doğruluğunu test edelim. Bu bağlamda hemen Win32 API help’imizi
açıyor ve CreateDesktop yazıyoruz. Bu fonksiyonun Group yada See also kısmına
baktığımızda EnumDesktops isimli fonksiyonu göreceğiz. Adından da anlaşıldığı gibi bu
fonksiyon bize işletim sistemindeki masaüstlerini verecek. Gelin birlikte tanımına bir göz
atalım;
1.
2.
3.
4.
5.
BOOL EnumDesktops(
HWINSTA hwinsta,
// handle to window station to
enumerate
DESKTOPENUMPROC lpEnumFunc, // points to application's
callback function
LPARAM lParam
// 32-bit value to pass to the callback
function
);
5
12
19
26
6
13
20
27
7
14
21
28
8
15
22
29
9
16
23
30
10 11
17 18
24 25
31
« Haz
Arşivler
Haziran 2010 (1)
Mayıs 2010 (1)
Nisan 2010 (3)
Ağustos 2009 (1)
Temmuz 2009 (2)
Haziran 2009 (7)
Mayıs 2009 (32)
ve Delphi’deki tanımı ise aşağıdaki gibidir.
1.
function EnumDesktops(hwinsta: HWINSTA; lpEnumFunc:
TFNDeskTopEnumProc; lParam: LPARAM): BOOL; stdcall;
Bu fonksiyonumuzda yine açıklamakta zorlanacağım, henüz tam manası ile hakim
olamadığım Window Statiton kavramına bir atıf var. Tanımda gözlemleyebileceğiniz birinci
parametrenin tipine dikkat edin: HWINSTA. Yani bir window station tutacağı(handle). Peki
Window Station da neyin nesi ? Window Station kendine has bir clipboard’u olan, kendine has
global atom tablosu olan, içinde birden fazla masaüstüne sahip olabilen; klavye, mouse ve
ekran ile etkileşim kurabildiğiniz bir nevi kapsayıcı güvenlik nesnesi. Bir makina üzerinde
birden fazla Window Station olabiliyor. Ama sadece winsta0 olarak adlandırılan birinci Window
Station’un interaktiflik özelliği bulunuyor. Bu güvenlik nesnesinin hangi ihtiyaçlara binaen var
olduğunu kestirebildiğimi söylesem pek doğru bir kelam etmiş sayılmam. Ancak Terminal
server’da her yapılan bağlantının kendi oturumunda(session) bir window station’a sahip
olduğunu ve bunun interaktif(kullanıcı ile etkileşimli) olduğunu öğrenmiş bulunuyorum.
Bu parametre hakkında ilerleyen zamanlarda kendi öğrenebildiklerim kadarı ile yeni
paylaşımlar yapmayı arzuluyorum, ama sanırım bu makalemiz için bu kadarı yeterlidir. Zaten
kendisini pek de fazla kullanmayacağız. Biz yine işletim sistemimizde birden fazla olduğunu
iddaa ettiğimiz masaüstlerimizin nasıl bulunacağı konusuna yani EnumDesktops‘a geri
dönelim isterseniz. Birinci parametresini zor da olsa geçebildiğimiz fonksiyonun ikinci
parametresi TFNDeskTopEnumProc türünde ve callback fonksiyon diye adlandırılan bir
Bağlantılar
Bir Türkçe Sevdalısı..
Delphi Türkiye Forum
Gürcan ÖZTÜRK
M.Fatih KÜÇÜKKELEPÇE
Memik YANIK Kişisel
Memik YANIK’ın Günlüğü
Nick Hodges
Sinan BARAN
Zafer Çelenk
PDFmyURL.com
fonksiyon pointer’dır. Yani bir fonksiyona işaret eden bir işaretçi. Win32 API dökümanında
aşağıdaki gibi tanımlanmıştır:
1.
2.
3.
4.
BOOL CALLBACK EnumDesktopProc(
LPTSTR lpszDesktop, // name of a desktop
LPARAM lParam
// value specified in EnumDesktops call
);
Ziyaretçi Bilgileri
Ziyaret: 4 / 12073
Delphi’ye ise aşağıdaki gibi çevireceğiz:
1.
function DesktopProc(DesktopName : LPTSTR; Param : LPARAM) :
Boolean; stdcall;
Metodun Delphi’deki tanımından sizinde gözlemleyebildiğiniz üzere metodun isminin bir önemi
yoktur. Yani illa EnumDesktopProc olması lüzumu yoktur. Gerçi okunaklığı arttırmak adına
genellikle API yardımındaki isimlendirme notasyonu tercih edilir ancak ben sizin özgür
olduğunuzu ifade edebilmek adına farklı bir isimlendirmeye gittim. Üçüncü parametre ise
EnumDesktops tarafından DesktopProc’a olduğu gibi geçilecek bir parametredir.
EnumDesktops fonksiyonu kısaca, kendisine geçilen ikinci parametredeki DesktopProc
fonksiyonunu işletim sistemindeki her desktop nesnesi için bir kere çağıracaktır. Şimdi gelelim
bu metodu nasıl kullanacağımıza:
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
TDesktop = class
private
fDesktops : TStrings;
public
constructor Create;
destructor Destroy; override;
Beğenilenler
Delphi 2010 (Weaver) ve TValue - 14 votes
Derinlemesine Threading..(3) - 13 votes
Derinlemesine Threading..(2) - 6 votes
Derinlemesine Threading..(1) - 6 votes
Yeni Veri Tipleri ve Operator Overloading - 4
votes
Win32 & .Net(Delphi->C#) - 4 votes
Delphi ve Google Maps API - 3 votes
TThread.WaitFor Bug.. - 3 votes
BITS(Background Intelligent Transfer Service)
ile sessiz sedasız download ;) - 3 votes
Bir Kiosk ve CreateDesktop macerası.. - 3
votes
procedure Refresh;
property Desktops : TStrings read fDesktops;
end;
function DesktopProc(DesktopName : LPTSTR; Param : LPARAM) :
Boolean; stdcall;
begin
TDesktop(Param).Desktops.Add(DesktopName);
Result := true;
// Burada true döndürmek önemlidir. Desktop arama işleminin
devam etmesini sağlar, false döndürülmesi bu metodu
çağıran EnumDesktops'un durmasına
//ve sonraki desktoplar için DesktopProc'u çağırmamasına
neden olur.
end;
constructor TDesktop.Create;
begin
Meta
Giriş
Yazılar RSS
Yorumlar RSS
WordPress.org
Etiketler-Liste
PDFmyURL.com
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
inherited Create;
fDesktops := TStringList.Create;
Refresh;
..
..
end;
procedure TDesktop.Refresh;
begin
Desktops.Clear;
EnumDesktops(GetProcessWindowStation, @DesktopProc,
Integer(Self));
end;
..
..
..
procedure TForm1.Button1Click(Sender : TObject);
var
Desktop : TDesktop;
begin
Desktop := TDesktop.Create;
ListBox1.Items := Desktop.Desktops; // ListBox1 nesnesi
TListBox türündedir.
Desktop.Free;
end;
Yukarıdaki kodumuzu çağırdımızda 3 adet desktop’un işletim sistemimizde varsayılan olarak
bulunduklarını gözlemleyeceksiniz. Bunlar sırası ile Default, Disconnect ve WinLogon
masaüstleridir. Default desktop’u; adından da anlayacağınız gibi hergün kullandığımız
masaüstümüzdür. Disconnect desktop’u Terminal server bağlantılarında kullanılan desktop,
son olarak da WinLogon desktop’u Win+L, Ctrl+Alt+Del ile geçtimiz kullanıcı girişinin olduğu
masaüstümüzdür. Bu masaüstlerinin ilginç ve kısıtlayıcı bazı yanlarından ilerleyen satırlarda
bahsedeceğim.
Bu arada son verdiğim kod örneğini ileride komple bir sınıf haline getireceğimiz TDesktop sınıfı
üzerinden anlatmayı uygun buldum. En son kaldığımız noktada bir desktop create
edebilmiştik. Ancak hala o desktop’a geçememiş ve birşeyler görememiştik. Gelin şimdi
ekranda görebileceğimiz ve haz duyabileceğimiz desktoplar arası geçişi sağlayan metoda
hayat verelim. Bunun için yine bir başka API fonksiyonu olan SwitchDesktop metodunu
kullanacağız. Yine herzaman olduğu gibi tanımlarına bir göz gezdirelim:
1.
2.
3.
BOOL SwitchDesktop(
HDESK hDesktop // handle of desktop to activate
);
ve yine herzamanki gibi Delphi tanımımız:
1.
function SwitchDesktop(hDesktop: HDESK): BOOL; stdcall;
Absolute
API
Byte Arrays Class Reference
COM CreateDesktop CreateProcess
CreateRemoteThread
CreateToolHelp32SnapShot
Function
DTS EnumDesktopProc EnumDesktops
Pointer GetCurrentProcess
GetIconInfo GetKeyState
GetLastInputInfo GetProcessMemoryInfo GetStartupInfo
Hacking Inheritance Interface JavaScript
Method Pointer Module32First Module32Next
OpenDesktop Persistance Pointer Procedure
Pointer
Process Process32First Process32Next
RTTI SetProcessWorkingSetSize SQL
Server Sw itchDesktop TerminateProcess
Reqursion
Thread Untyped Parameters VirtualAllocEx
WaitForSingleObject
VirtualFreeEx
WriteProcessMemory
Delphi About
Auto Select All The Text For TCustomEdit On
Mouse Click 29 Haziran 2010
Memory Leak Notification in Delphi - Report
Memory Leak on Program Exit 27 Haziran
2010
PCRE Workbench - Regular Expression Test
Tool - Source Code Delphi Application 22
Haziran 2010
Deleting Dataset Records In a Loop - Poll
Results - Why All Records Are Not Deleted 21
Haziran 2010
Force TListView's Edit Mode using a Keyboard
Shortcut 17 Haziran 2010
Implementing On Item Click / Double Click for
Delphi's TListView control 16 Haziran 2010
Run Your Delphi Application in Full Screen Implement "F11 - Full Screen" 14 Haziran 2010
PDFmyURL.com
Nihayet son derece kısa bir tanıma sahip bir metodumuz oldu.
Ancak yine de
anlatmakta fayda var kanısındayım. Bu fonksiyon, CreateDesktop yada OpenDesktop API
fonksiyonlarından geriye dönen desktop’un tutacağını(handle) kendisine parametre olarak alır
ve anında belirtilen masaüstüne geçiş yapar. Bunun bir istisnası, geçiş yapılmak istenilen
masaüstünün varsayılan Window Station‘da olmaması durumudur ki bu durumda hata
verecektir. Şimdi müsaade ederseniz daha önce tanımına yer verdiğimiz CreateDesktop
metodunu ve henüz içeriğini yazmadığımız SwitchDesktop metodunu ilgili sınıfımız TDesktop’a
ekleyelim:
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
TDesktop = class
..
..
procedure CreateDesktop(const Name : String);
procedure SwitchDesktop(const Name : String);
end;
procedure TDesktop.CreateDesktop(const Name : String);
var
Handle : HDESK;
begin
Handle := Windows.CreateDesktop(PChar(Name), nil, nil,
DF_ALLOWOTHERACCOUNTHOOK, DESKTOP_ALL, nil);
if Handle = 0 then
raise Exception.Create(Name + ' isimli desktop
oluşturulamadı.!');
Desktops.Add(Name);
end;
procedure TDesktop.SwitchDesktop(const Name : String);
var
Index : Integer;
Handle: HDESK;
begin
Index := Desktops.IndexOf(Name);
if Index = -1 then
raise Exception.Create(Name + ' isimli desktop mevcut
değil.!');
Handle := OpenDesktop(PChar(Name),
DF_ALLOWOTHERACCOUNTHOOK, false, DESKTOP_ALL);
if Handle = 0 then
raise Exception.Create(Name + ' isimli desktop
açılamadı.!');
Windows.SwitchDesktop(Handle);
CloseDesktop(Handle);
Implement "F11 - Full Screen" 14 Haziran 2010
Displaying Enumerated Properties in a
Selectable List - Run-Time Enum Selection in
Delphi 10 Haziran 2010
How Do You Delete Dataset Records In a
Loop? 08 Haziran 2010
Display Custom Hints for Status Bar Panels 07
Haziran 2010
Sık Ziyaret Edilenler
Sayfa: Home
(16059)
Delphi ve Google Maps API
(4132)
Delphi ve Google Maps API
(1973)
Nedir bu Thread’lerden çektiğimiz..!
(1444)
Delphi & Animated Flash Charts(Fusion Charts)
(1174)
Delphi & JavaScript Kardeşliği
(933)
Delphi 2010 (Weaver) ve TValue
(918)
Derinlemesine Threading..(1)
(886)
Derinlemesine Threading..(2)
(695)
Win32 & .Net(Delphi->C#)
(617)
Kategori: Delphi
(613)
Bir Kiosk ve CreateDesktop macerası..
(568)
Sayfa: Hakkında
(563)
PDFmyURL.com
34.
end;
SwitchDesktop metodumuzda öncelikle geçiş yapmak istediğimiz desktop’un var olup
olmadığını kontrol ediyor ardından da OpenDesktop metodu vasıtası ile o desktop’un handle’ını
elde ediyoruz. Ardından SwitchDesktop’umuzu çalıştırıyoruz ve yeni masaüstümüz
karşımızda. Sonrada hafıza kullanımına değer veren bir programcı olduğumuz için
OpenDesktop ile hafızada ayırdığımız bir miktar yeri hemen serbest bırakıyoruz. Ancak sakın
bu kodu hemen denemeyin. Biraz daha sabır istirham edeceğim sizlerden. Eğer bu kodu
hemen bu hali ile denerseniz, benim defalarca yapmış olduğum gibi makinanızı restart
etmekten başka bir çareniz kalmaz. İşletim sisteminde oluşturulan her desktop nesnesi kendi
etki alanı içinde çalışmaktadır. Diğer desktoplardaki pencerelerle iletişim halinde değildir,
onlarla haberleşemez. Alt+Tab çağrılarınız diğer desktop’taki pencereler arasında geçişinizi
sağlamaz. Task Manager’ı açma çabalarınız da sonuçsuz kalacaktır. İşletim sisteminin bir
bug’u olduğunu düşündüğüm Task Manager’ı açma çabası da aslında karşılıksız kalmaz ama
Task Manager maalesef beklediğiniz desktop’da değil Default desktop’ta açılacaktır. Dolayısı
ile bu kodu şu hali ile çalıştırmak, makinanızı restart etmeniz gerektiğinin güçlü bir delilidir.
Makinamı 7-8 kez restart etmek durumunda kaldıktan sonra TDesktop sınıfına aşağıdaki
metodu yazmayı uygun buldum;
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
procedure TDesktop.SwitchDefaultDesktop;
var
Handle: HDESK;
begin
Handle := OpenDesktop(PChar('WinSta0\Default'),
DF_ALLOWOTHERACCOUNTHOOK, false, DESKTOP_ALL);
if Handle = 0 then // Çifte güvenlik. Bazı makinalarda
WinSta0\Default isminde olabileceğini okudum, işi şansa
bırakmak istemedim.
begin
Handle := OpenDesktop(PChar('Default'),
DF_ALLOWOTHERACCOUNTHOOK, false, DESKTOP_ALL);
if Handle = 0 then
raise Exception.Create('Default desktop açılamadı.!');
end;
Windows.SwitchDesktop(Handle);
CloseDesktop(Handle);
end;
Artık arzu ederseniz ilk denemenizi yapabilirsiniz. Şimdi yazacağımız kod ile restart yapmak
zorunda kalmayacaksınız. Buyurun bunca uğraşının sonunda artık desktop’umuzu görelim:
01.
02.
03.
04.
05.
06.
07.
procedure TForm1.Button1Click(Sender : TObject);
var
Desktop : TDesktop;
begin
Desktop := TDesktop.Create;
Desktop.CreateDesktop('Deneme');
Desktop.SwitchDesktop('Deneme');
(563)
TThread.WaitFor Bug..
(540)
Delphi 2010 (Weaver) ve TValue
(530)
Oylama..
Sitedeki makaleleri yararlı buluyor musunuz
?
Evet, yararlı ama yetersiz.
Evet, son derece yararlı.
Evet, mükemmel.
Hayır, yararlı değil.
Hayır, hem yararlı değil, hem de yetersiz.
Hayır, rezalet.
Vote
View Results
Delphi'nin hangi sürümünü kullanıyorsunuz
?
Delphi 5 yada öncesi
Delphi 6
Delphi 7
Delphi 8
Delphi 2005
Delphi 2006
Delphi 2007
PDFmyURL.com
08.
09.
10.
11.
Sleep(25000); // 25 sn bekle..
Desktop.SwitchDefaultDesktop;
Desktop.Free;
end;
Kodumuz Deneme isminde bir masaüstü oluşturacak ve ona geçiş yapacak, ardından 25
saniye boyunca siz desktopunuza bakarken varsayılan masaüstünüze geri döneceksiniz.
Sizlerin de farkettiği gibi yeni oluşturduğumuz masaüstümüzde hiçbir şey yoktur. Ne
masaüstü resmi, ne başlat menüsü, ne masaüstü simgeleri, ne de taskbar. Uygulamamızda
orada değil. Şu hali ile bu masaüstü bizim hiç bir işimize yaramıyor. Bizim; yazacağımız
uygulamaları yeni desktop’ta çalıştırabilmeye kesinlikle ihtiyacımız var. Aksi taktirde bunca
anlatılanın hiç bir ehemmiyeti olmazdı. Arzu ederseniz onu da yapalım. İstediğimiz herhangi bir
uygulamayı diğer bir masaüstünde çalıştırabilmek için CreateProcess isimli API metoduna
gereksinimimiz olacak. Buyrun tanımına bakalım:
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
1.
2.
3.
4.
5.
Delphi 2009
Delphi 2010
Vote
View Results
BOOL CreateProcess(
LPCTSTR lpApplicationName, // pointer to name of
executable module
LPTSTR lpCommandLine,
// pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to
process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes,
// pointer to
thread security attributes
BOOL bInheritHandles,
// handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment,
// pointer to new environment
block
LPCTSTR lpCurrentDirectory, // pointer to current
directory name
LPSTARTUPINFO lpStartupInfo,
// pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to
PROCESS_INFORMATION
);
function CreateProcess(lpApplicationName: PChar;
lpCommandLine: PChar;
lpProcessAttributes, lpThreadAttributes:
PSecurityAttributes;
bInheritHandles: BOOL; dwCreationFlags: DWORD;
lpEnvironment: Pointer;
lpCurrentDirectory: PChar; const lpStartupInfo:
TStartupInfo;
var lpProcessInformation: TProcessInformation): BOOL;
stdcall;
Görüldüğü gibi pek çok parametresi var. Ben bunlardan birkaçına değinip diğerlerini araştırmayı
siz değerli okuyucularıma bırakacağım. Bu parametrelerden en önemlisi lpCommandLine isimli
olan peremetredir. Bu parametre çalıştırmak istediğimiz dosyanın path bilgisini yazacağımız
yerdir. İkinci ve en can alıcı parametremiz ise lpStartupInfo isimli parametredir. Bu parametre
PDFmyURL.com
üzerinde biraz durmamız gerekiyor. Herzamanki gibi TStartupInfo türünde olan parametremizin
tanımına bir göz gezdirelim:
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
_STARTUPINFOA = record
cb: DWORD;
lpReserved: Pointer;
lpDesktop: Pointer;
lpTitle: Pointer;
dwX: DWORD;
dwY: DWORD;
dwXSize: DWORD;
dwYSize: DWORD;
dwXCountChars: DWORD;
dwYCountChars: DWORD;
dwFillAttribute: DWORD;
dwFlags: DWORD;
wShowWindow: Word;
cbReserved2: Word;
lpReserved2: PByte;
hStdInput: THandle;
hStdOutput: THandle;
hStdError: THandle;
end;
TStartupInfo = _STARTUPINFOA;
Gördüğünüz gibi bu bir record. Bu record’un içerisinde uygulamız için hayati derecede öneme
sahip olan bir parametre mevcut. O da; pointer türünde tanımlanmış olan lpDesktop. İşte bu
bizim desktopumuzun adını geçeceğimiz yerden başkası değil. Bir diğer önemli parametre ise
DWord tipli cb isimli parametredir. Bu parametreye de SizeOf(TStartupInfo) gibi bir atama
yapacağız. Dilerseniz herhangi bir masaüstünde herhangi bir uygulamanın çalıştırılması
becerisine haiz metodumuzu da sınıfımıza ekleyelim:
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
procedure TDesktop.ExecuteProgram(const Desktop, ExeName:
String);
var
Index : Integer;
StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
begin
Index := Desktops.IndexOf(Desktop);
if Index = -1 then
raise Exception.Create(Desktop + ' isimli desktop mevcut
değil.!');
if not FileExists(ExeName) then
raise Exception.Create(ExeName + ' isimli dosya mevcut
değil.!');
PDFmyURL.com
14.
15.
16.
17.
18.
19.
20.
21.
FillChar(StartupInfo, SizeOf(TStartupInfo), 0); // Recordun
içeriğini temizliyoruz..
StartupInfo.cb := SizeOf(TStartupInfo);
StartupInfo.lpDesktop := PChar(Desktop); // PChar da bir
pointer tipidir.
if not CreateProcess(nil, PChar(ExeName), nil, nil, false,
NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo,
ProcessInfo) then
raise Exception.Create(ExeName + ' isimli uygulama ' +
#13#10 + Desktop + ' isimli masaüstünde
çalıştırılamadı.!');
end;
Şimdi bir önceki örneğimize geri dönelim ve o anda çalışan uygulamamızı diğer masaüstünde
de çalıştıralım:
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
procedure TForm1.Button1Click(Sender : TObject);
var
Desktop : TDesktop;
begin
Desktop := TDesktop.Create;
Desktop.CreateDesktop('Deneme');
Desktop.SwitchDesktop('Deneme');
Desktop.ExecuteProgram('Deneme', Application.ExeName);
Sleep(25000); // 25 sn bekle..
Desktop.SwitchDefaultDesktop;
Desktop.Free;
end;
Bu kodu deneyince göreceğiniz gibi, yeni bir masaüstünüz olacak ve çalışan uygulamanızın
bir kopyası da diğer masaüstünde hazır halde sizi bekliyor olacaktır. Buraya kadar herşey
sorunsuz(7-8 defa restart etmeyi saymaz isek) gitti. Herhangi bir mâni ile karşılaşmadık.
Bundan sonra tercihlerinize göre yine karşılaşmayabilirsiniz. Ama sizlerde benim gibi hafıza
kullanımı konusunda son derece titizseniz o zaman sizleri bazı sorunlar bekliyor. Benim bu
makaleyi yazmaktan imtina ettiğim sorunlar. Herne kadar o sorunların hepsini aşsam da izahı
son derece zor hususlar. Ancak yine de elimden geldiğince dilim döndüğünce izaha gayret
edeyim.
Nedir bu sorunlar diye iyice meraklanmış olabilirsiniz. Sizleri daha fazla merakta bırakmadan
anlatayım. Şimdi bir senaryo üzerinden hareket edelim. Bu senaryoda yeni oluşturduğumuz
masaüstümüzde başlat menüsünü, masaüstü simgelerini ve görev çubuğunu görmek
istediğimizi düşünelim. O zaman daha evvel yazdığımız ExecuteProgram metodumuz ile
explorer.exe‘nin de ilgili masaüstünde çalıştırılması gerekecektir.
Bunu yapmamız kolay, ancak sorun çalıştırmış olduğumuz explorer.exe’nin sonlandırılması
sırasında ortaya çıkacak. Zaten varsayılan masaüstümüzde çalışan bir explorer.exe’miz vardı,
şimdi ikinci masaüstünde çalışan bir tane daha oldu ve biz hafızayı iktisatlı kullanmak
PDFmyURL.com
istiyoruz. Dolayısı ile ikinci masaüstü için çalıştırdığımız explorer.exe’nin sonlandırılması
gerekli.
Bu problem aklımıza daha önce kullanımını anlattığımız TStartupInfo yapısını getiriyor ve
araştırmalara başlıyoruz. Acaba çalışan uygulamalardan elde edebileceğimiz TStarupInfo gibi
bir yapı var mı ? Bu bağlamda API help’te dolaşırken GetStartupInfo gibi bir metoda rastlıyoruz.
Tanımı aşağıdaki gibidir:
1.
2.
3.
1.
VOID GetStartupInfo(
LPSTARTUPINFO lpStartupInfo
structure
);
// address of STARTUPINFO
procedure GetStartupInfo(var lpStartupInfo: TStartupInfo);
stdcall;
Ancak incelemelerimiz bu metodun o anda çalışan uygulamanın bilgilerini döndüreceğini
söylüyor. Oysaki bizim explorer.exe’nin bilgilerine ihtiyacımız vardı.! İşte bu noktada aslında bir
başka makalenin konusu olabilecek kadar derin bir araştırma ve ayrıma gitmemiz gerekiyor.
Uzunca bir müddet düşündükten sonra, sonlandırmak istediğimiz explorer.exe’nin hangisi
olduğuna karar verilemediği için hafızada çalışır halde bulunan her iki uygulamaya da bulaşan
bir dll yazmaya karar verdim. Bu DLL ilgili exe’lere bulaştıktan sonra GetStartupInfo metodunu
o exe içinde çalıştırmalı ve sonucu explorer.exe’yi çalıştıran uygulamaya yada diğer
masaüstünde hali hazırda çalışan uygulamamızın kopyasına göndermeliydi. Hafızada çalışan
uygulamaya bulaşan kodu uzunca bir araştırma sürecinden sonra mantığı ile anlayıp
kodlamıştım ancak bu sefer de bulaşan DLL’in bulaştığı kaynaktan silinmesi gerekiyordu.
PDFmyURL.com
Bu sorun da aşıldıktan sonra, artık hafızaki istediğimiz herhangi bir uygulamaya yüklenebilen
ve tekrar silinebilen bir mekanizmaya sahiptik. Artık bu mekanizma bize bulaştığı
uygulamaların içinde GetStartupInfo metodundan elde ettiği değerli desktop name bilgisini
döndürebilirdi. Bir DLL ile bir EXE’nin birbirleri arasında haberleşme birden fazla yöntem ile
sağlanabilir. Bu tarz işlemlere genellikle Interprocess Comminication (IPC) adı verilir. Hafızada
paylaşılan bir alana yazılan veriler diğer uygulama tarafından görünür kılınabilir, yada daha
basit bir yöntem ile DLL ile EXE arasında mesajlaşma API’leri vasıtası ile(SendMessage,
PostMessage) haberleşilebilir. Ancak burada kesinlikle unutulmaması gereken bir şeyi daha
önce söylediğim halde yeniden ifade etmekte yarar görüyorum. Birbirinden farklı
desktoplardaki uygulamalar, birbirleri ile bu şekillerde kesinlikle haberleşemezler. Bu durum
hasıl olduğunda socket haberleşmesi daha genel ve etkin bir çözüm olabilir. Bu vesile ile
bende iletişim yöntemi olarak socket haberleşmesini tercih ettim. Böylece hangi desktop’ta
olduğunuzdan bağımsız olarak sistemin hatasız çalışmasını garanti altına almış olduk.
Sorun üzerinde bunca dönüp dolaştıktan sonra birazda çözüme doğru yol alalım.Şimdi
yapmamız gereken 3 şey var.
Çalışan uygulamalara bulaşan bir kod yazmak.
Çalışan uygulamalara bulaşan kodun temizlik kodunu yazmak
Sonlandırmak istediğimiz process’in bulunmasına müteakip çalışacak sonlandırma kodunu
yazmak.
Sırası ile hepsini yazalım:
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
procedure InjectProcess(const RemoteProcessID : Cardinal;
const DLLName : String);
var
RemoteProcessHandle,
BytesWritten,
ThreadID,
RemoteThreadHandle : Cardinal;
pDLL : Pointer;
begin
if not FileExists(DLLName) then
raise Exception.Create(InttoStr(RemoteProcessID) + '->' +
DLLName + ' bulunamadı.!');
PDFmyURL.com
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
RemoteProcessHandle := OpenProcess(PROCESS_ALL_ACCESS,
false, RemoteProcessID);
if RemoteProcessHandle <> 0 then
begin
pDLL := VirtualAllocEx(RemoteProcessHandle, nil,
Length(DLLName), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if Assigned(pDLL) then
if WriteProcessMemory(RemoteProcessHandle, pDLL,
PChar(DLLName), Length(DLLName), BytesWritten) then
begin
RemoteThreadHandle :=
CreateRemoteThread(RemoteProcessHandle, nil, 0,
GetProcAddress(GetModuleHandle('kernel32.dll'),
'LoadLibraryA'), pDLL, 0, ThreadID);
if RemoteThreadHandle <> 0 then
begin
WaitForSingleObject(RemoteThreadHandle, 2000);
CloseHandle(RemoteThreadHandle);
end;
end;
end; // if RemoteProcessHandle <> 0 then
if Assigned(pDLL) then
VirtualFreeEx(RemoteProcessHandle, pDLL, 0, MEM_RELEASE
);
CloseHandle(RemoteProcessHandle);
end;
Şimdi sıra temizlik kodunda:
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
procedure CleanProcess(const RemoteProcessID : Cardinal;
const DLLName : String);
var
SnapshotHandle,
RemoteProcessHandle,
RemoteThreadHandle,
ThreadID : Cardinal;
meCurrent : TModuleEntry32;
found : Boolean;
Module: String;
begin
if not FileExists(DLLName) then
raise Exception.Create(InttoStr(RemoteProcessID) + '->' +
DLLName + ' bulunamadı.!');
PDFmyURL.com
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
SnapshotHandle :=
CreateToolHelp32SnapShot(TH32CS_SNAPMODULE,
RemoteProcessID);
meCurrent.dwSize := SizeOf(TModuleEntry32);
Module32First(SnapshotHandle, meCurrent);
found := false;
while 1 <> 2 do
begin
Module := meCurrent.szExePath;
if LowerCase(Module) = LowerCase(DLLName) then
begin
found := true;
Break;
end;
if not Module32Next(SnapshotHandle, meCurrent) then
Break;
end;
if not found then
begin
CloseHandle(SnapshotHandle);
raise Exception.Create('Remote uygulamada istenilen modül
bulunamadı.!');
end;
RemoteProcessHandle := OpenProcess(PROCESS_ALL_ACCESS,
false, RemoteProcessID);
if RemoteProcessHandle <> 0 then
begin
RemoteThreadHandle :=
CreateRemoteThread(RemoteProcessHandle, nil, 0,
GetProcAddress(GetModuleHandle('kernel32.dll'),
'FreeLibrary'), meCurrent.modBaseAddr, 0, ThreadID);
if RemoteThreadHandle <> 0 then
begin
WaitForSingleObject(RemoteThreadHandle, 2000);
CloseHandle(RemoteThreadHandle);
end;
end;
CloseHandle(RemoteProcessHandle);
CloseHandle(SnapshotHandle);
end;
Ve nihayet bulunan process’in yok edilmesini sağlayan metodumuz:
PDFmyURL.com
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
procedure KillProcess(const ProcessID : Cardinal);
var
ProcessHandle : Cardinal;
begin
if ProcessId <> 0 then
begin
ProcessHandle := OpenProcess(PROCESS_TERMINATE, false,
ProcessID);
if ProcessHandle <> 0 then
begin
try
TerminateProcess(ProcessHandle, 0);
finally
CloseHandle(ProcessHandle);
end;
end;
end;
end;
Daha fazla ilerlemeden önce ne yaptığımız hakkında az çok malümat vermeye çalışalım.
Bulaşma kodunda, öncelikle bulaşacağımız process’i OpenProcess ile açıyoruz. Böylelikle
bulaşacağımız process’in handle’ını elde etmiş oluyoruz. Hemen ardından VirtualAllocEx ile o
process’in kullandığı hafıza bloğunda DLL’imizin path’i ile birlikte adının sığabileceği kadar bir
hafıza tahsis ediyoruz. Bu tahsisattan geriye dönen pointer ayrılmış hafıza bölgesini işaret
ediyor.Daha sonra WriteProcessMemory ile bulaşacağımız exe’nin ayrılmış olan hafıza
bölgesine DLL’imizin adını yazıyoruz. Ve en can alıcı kısım olan CreateRemoteThread metodu
vasıtası ile DLL’imizi çalıştırıyoruz. CreateRemoteThread belirtilen process’in belirtilen hafıza
bölgesindeki değeri parametre alarak belirtilen metodu çalıştırmakla yükümlüdür. Yani bizim
örneğimizde pDLL isimli hafıza bölgesini(ki içinde DLL’imizin adı var) LoadLibraryA metoduna
parametre olarak geçecek. Bildiğiniz gibi LoadLibraryA DLL kütüphanelerimizi dinamik olarak
yüklemek için kullandığımız Windows API metodudur. Bulaşma işleminin temelinde bu
mekanizma yatmaktadır. İlk bakışta karmaşık görünse de , anlamaya çalışarak ilerlediğinizde
o derece zor ve karmaşık olmadığını göreceksiniz. Yükleme kodunun tam zıttı olan kodun beni
biraz daha uğraştırdığını itiraf etmeliyim. Bu kodda processler içindeki modüllerin hepsini
dolaşmak ve kendi modülünüzü(yani DLL’inizi) bulmak ve ardından yine CreateRemoteThread
API’sine bu sefer FreeLibrary metodunu geçerek temizlik işlemini yapmanız gerekiyor.
Sizlerinde farkedeceği gibi, DLL’imizin yüklenmesi sırasında çalışan bazı kodlar var ve biz
henüz bu kodların neye benzedikleri hakkında fikir sahibi değiliz. Arzu ederseniz biraz da
DLL’imizin kodlarına göz gezdirelim:
01.
02.
03.
04.
05.
06.
07.
library RemoteDLL;
uses
SysUtils,
Classes,
Windows,
Dialogs,
PDFmyURL.com
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
Messages,
IdTcpClient;
{$R *.res}
const
LogFile = 'c:\CreateRemoteThread.txt';
procedure Log(const Message : String);
begin
with TStringList.Create do
begin
if FileExists(LogFile) then LoadFromFile(LogFile);
Add(Message);
SaveToFile(LogFile);
Free;
end;
end;
procedure EntryPointProc(Reason : Integer);
var
si : TStartupInfo;
p : PChar;
str: String;
client : TIdTCPClient;
begin
case Reason of
DLL_PROCESS_ATTACH: //1
begin
FillChar(si, SizeOf(TStartupInfo), 0);
si.cb := SizeOf(TStartupInfo);
GetStartupInfo(si);
p := si.lpDesktop;
str := p;
try
client := TIdTCPClient.Create(nil);
try
client.Host := '127.0.0.1';
client.Port := 9999;
client.Connect();
client.WriteLn(str + ',' +
InttoStr(GetCurrentProcessId()));
client.Disconnect;
except on E: Exception do Log('Connection Problem:'
+ E.Message);
end;
finally
client.Disconnect;
client.Free;
PDFmyURL.com
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
end;
Log('DLL_PROCESS_ATTACH:' + str + '/' +
TimeToStr(Time) + '/' +
InttoStr(GetCurrentProcessId()));
end;
DLL_THREAD_ATTACH:
//2
begin
end;
DLL_PROCESS_DETACH: //3
begin
Log('DLL_PROCESS_DETACH:' + TimeToStr(Time));
end;
DLL_THREAD_DETACH:
//0
begin
end;
end;
end;
begin
DLLProc := @EntryPointProc;
DLLProc(DLL_PROCESS_ATTACH);
end.
Görüldüğü gibi DLL’imiz hafızaya yüklenir yüklenmez DLL_PROCESS_ATTACH bölümüne
gidiyor ve bir socket bağlantısı vasıtası ile gönderilmesi gereken mesajı gönderiyor. Şimdi sıra
TDesktop sınıfımızın CloseRunningProcesses isimli metodunu yazmaya geldi. Buyurun onu da
yazıp makalemizin sonlarına doğru ilerleyelim:
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
procedure TDesktop.CloseRunningProcesses(const Desktop:
String;
Processes: array of String; const InjectDLLFile : String);
var
Index,
iCounter : Integer;
ProcessName : String;
ProcessList : TStrings;
peCurrent : TProcessEntry32;
SnapshotHandle : Cardinal;
TCPServer : TIdTCPServer;
pItem : TProcessItem;
begin
Index := Desktops.IndexOf(Desktop);
if Index = -1 then
raise Exception.Create(Desktop + ' isimli desktop mevcut
değil.!');
ProcessList := TStringList.Create;
PDFmyURL.com
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
TCPServer := TIdTCPServer.Create(nil);
try
TCPServer.Bindings.Clear;
with TCPServer.Bindings.Add do
begin
IP := '127.0.0.1';
Port := 9999;
end;
TCPServer.OnExecute := TCPServerExecuteEvent;
TCPServer.Active := true;
for iCounter := Low(Processes) to High(Processes) do
begin
ProcessName := Processes[iCounter];
ProcessName := ExtractFileName(ProcessName); // Path
şeklinde olmamalı..
ProcessList.Add(ProcessName);
end;
InjectCount := 0;
SnapshotHandle :=
CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
peCurrent.dwSize := SizeOf(TProcessEntry32);
Process32First(SnapshotHandle, peCurrent);
while 1 <> 2 do
begin
ProcessName := peCurrent.szExeFile;
if ProcessList.IndexOf(ProcessName) <> -1 then
begin
Inc(InjectCount);
InjectProcess(peCurrent.th32ProcessID,
InjectDLLFile); // Load &amp;amp;amp;amp;amp;amp;
Execute DLL
CleanProcess (peCurrent.th32ProcessID,
InjectDLLFile); // UnLoad DLL
end;
if not Process32Next(SnapshotHandle, peCurrent) then
Break;
end;
while InjectCount > 0 do Application.ProcessMessages;
for iCounter := 0 to KillProcessList.Count - 1 do
begin
try
pItem := TProcessItem(KillProcessList[iCounter]);
if pItem <> nil then
PDFmyURL.com
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
if pItem.Name = Desktop then
KillProcess(pItem.Handle);
except
end;
end;
finally
ProcessList.Free;
TCPServer.Active := false;
TCPServer.OnExecute := nil;
TCPServer.Free;
end;
CloseHandle(SnapshotHandle);
end;
Geriye kalan kodlar pek de ehemmiyetli kodlar değil, çeşitli kontroller, silinmesi istenilen
uygulamaların listesini tutan burada anlatmaya değer olmayan kod parçacıkları. Bu sebeple
onları anlatma gereği duymuyorum. Ancak kodları daha rahat ve bir bütün halinde
inceleyebilmeniz adına ilgili sınıfın pas dosyasını da buraya koyuyorum.
Çok uzun bir makale oldu gerçekten, sabırla okuyabilenlere teşekkür ederim.
Saygılar, sevgiler..
Not: CleanProcess metodunu explorer.exe ve diğer şüphelendiğiniz processler
için çalıştırabilirsiniz. Benim explorer.exe ile ilgili testlerim sırasında FlashGet
programının bir DLL’inin explorer.exe içerisinde yüklü olduğunu gördüm. Bu
normal mi değil mi tam emin olmamakla birlikte yine de şüphe çekici..
[Translate]
17 Comments
Özkan Danacı
on Mayıs 22nd, 2009
Okuyorum.. Okuyorum.. hala Okuyorum..
PDFmyURL.com
Tuğrul HELVACI
on Mayıs 22nd, 2009
Olcay DAĞLI
on Mayıs 23rd, 2009
Sanırım biraz uzun yazmışım
Uzun uğraşılar sonucu elde etmiş olduğun böylesi bir bilgiyi daha zor
ve uzun bir uğraşı ile yazıya döküp anlatabildiğin için tebrik ederim
hocam…
Yanlız bir şey belirteyim makale o kadar uzun gelmiyor okuyunca,
zira gayet akıcı yazmışsın, eline sağlık hocam
Veli BOZATLI
on Haziran 1st, 2009
Tuğrul HELVACI
Sanal alemde gerçekten böyle yararlı ve değerli (araştırılması,
oluşturulması, yazılması vs. zor) bilgileri paylaşan kişilerin olduğunu
görmek beni çok mutlu ediyor.
Elimizden sadece bir kuru teşekkür etmek geliyor :
Hiçbir karşılık beklemeksizin bilgilerini paylaşanlardan Allah razı
olsun…
Allah, “Allah razı olsun” diyenden de demiyenden de razı olsun..
on Haziran 1st, 2009
Numan
on Haziran 26th, 2009
M akaleyi henüz okumadım ama hemen teşekkür etmek istedim. Ben
Delphi de yeniyim, CreateDesktop olayını visual basic de
kullanıyordum, ancak bunu Delphi ye bir çırpıda dönüştürmek şu an
benim için çok zor bir olaydı. Bu makaleyi henüz okumadım ancak
olayı bildiğimden dolayı bunun bana çok faydalı olacağından emin
gibiyim, şimdiden teşekkürler aro.
PDFmyURL.com
Tuğrul HELVACI
Allah cümlemizden razı olsun.
on Haziran 26th, 2009
Soylu OItu KAYA
on Ağustos 1st, 2009
Açıkcası çok güzel açıklamalar ve farklı bir yaklaşım.
Programlama konusunda bu tarz makaleleri okurken bazen bir satırın
açıklamasını gördüğümde o satırdaki komutun araştırmasına
giriyorum ve bir bakıyorum 6 gün geçmiş ve ben o satırlardaki tüm
komutları en detaylı şekilde öğrenmişim. Tabiki bunu kendi
yazılımıma adapte etme aşamasına gelince iş biraz farklılaşıyor kendi
yazılımımda 5 satır kodu kullanıyorum öğrendiğim 500 sayfa
açıklama gereksiz kalıyor
Biraz düşündüm ve dedim ki kendi
kendime bu arkadaş bu kadar yazmış bunun proje dosyasını yada
pas dosyasını niye koymamış sonralarda fark ettim ki en altta 1
satırcık yere
” ilgili sınıfın pas dosyasını da buraya koyuyorum.” ibaresi ile pas
dosyasını koymuş tebrikler. Proje dosyalarından inceleme yapmak
bazen çok daha seri oluyor. Her komuta her yerde ihtiyaç
olmayabiliyor. Çalışmalarında başarılar.
Bora ÇAYIR
on Ağustos 28th, 2009
İsmail Aktaş
(SHURZAN)
on Ekim 24th, 2009
Delphiyle ilgili hereşeye varım siteyi bugün keşfettim
konular guzel
M erhaba Tuğrul,
Yazmış olduğun makleyi ve bu sayfanı, Kendi projemde geliştimek
istediğim bir çalışmaya ait başka bir win32 API hakkında bilgi
ararken rastgeldim, doğrusu konuya hakim ve akıcı bir uslupta
ayrıntılara girmişsin ki çok başarılı eline sağlık.
Ben C++ yazılım dilinde BDS 2006 ortamında proje geliştiriyorum.
Her ne kadar Delphi’ci değilsem de okuyabiliyorum.
PDFmyURL.com
Windows XP için çeşitili ayar ve düzenlemeler yapan Shurzanop 2.0
için makalenizde geçen çalışmayı da uygulamak istiyorum. Eğer bir
mahsuru yoksa kodlamayı C++ dili ile geliştirip kullanacağım.
Bu makaleniz için teşekkürler, başka makalelerde bekliyoruz.
Tuğrul HELVACI
on Ekim 26th, 2009
mkysoft
M erhaba İsmail bey, elbette gönlünüzce kullanabilirsiniz.
Çalışmalarınızda başarılar dilerim.
Çok güzel bir makale olmuş, teşekkür ederim.
on Ekim 31st, 2009
mesut
on Mart 11th, 2010
Tuğrul HELVACI
on Mart 16th, 2010
hocam çok teşekkür ederim çok güzle bir makale olmuş.
benim ufak bir sorum var .
ben TM emoryStream nesnesi ile şifrelediğim bir dosyayı ram da
çalıştırmak istiyorum yani bir yere kopyalanıp oradan çalışmasını
istemiyorum.şifrelenmiş dosyayı direk çalıştıracak. makalenizde
writeproccesmemory komutunu ksıa analtmışsınız acaba bu komutu
kulalnarak direk ram da çalıştırabilirmiyim veya hangi kodu
kullanmalıyım
teşekkür ederim.. ayrıetten msn desteğiniz olursa sevinirim.
M esut bey, WriteProcessM emory ile ilgili daha detaylı bilgi
paylaşımı virüs ve trojan yapımcılarının işine yarar ve onların ilgi
alanıdır genellikle. Zaten konuyu izah edebilmek adına biraz da olsa
zararlı olabilecek içeriklere girdik, daha detaylarına girmeyelim
PDFmyURL.com
Mehmet Erdem
Korkmaz
Güzel bir çalışma olmuş. Emeğine sağlık. Bana yol gösterici olmasına
rağmen hala yapmayı başaramadığım bir meseleyi sormak isterim.
on Mart 17th, 2010
Benim yapmak istediğim şey winlogon ekranına geçilse bile o ekranın
görüntüsünü alabilmek. Bunu bir türlü başaramadım.
MURAT
on Haziran 7th, 2010
Tuğrul HELVACI
Helal olsun kardeş,
Harika olmuş baya uğraşmıssın
eline sağlık.
Teşekkür ederim, sağolun.
on Haziran 7th, 2010
Share your comment
Name (required)
Mail (required)
Website
PDFmyURL.com
Son Yorumlar
Yeni Eklenenler
Linkler
Yorumunuza teşekkürler. Aslında operatör aşırı
yüklemenin sınıflarda pek bir avantaj... by Tuğrul
HELVACI
Yeni Veri Tipleri ve Operator Overloading
Bir Türkçe Sevdalısı.. - Taha EKREM
Interface Nedir, Nerelerde ve Neden Kullanırız ?
Delphi Türkiye Forum
Merhaba, Ben ilk olarak merakımdan dolayı uğraştığım
C++ dilinde görmüştüm Operatör... by Zafer Çelenk
Derinlemesine Threading..(3)
Gürcan ÖZTÜRK - Gürcan ÖZTÜRK
SQL’de Benzerlik Algoritmaları…
M.Fatih KÜÇÜKKELEPÇE
Full Text Searching…
Memik YANIK Kişisel
Delphi 2010 (Weaver) ve TValue
Memik YANIK’ın Günlüğü
Derinlemesine Threading..(2)
Nick Hodges
Merhaba, makaleyi yazdığım zaman kodlarda bir sorun
yoktu. Belki Google Maps'de bir şeyler... by Tuğrul
HELVACI
Merhaba Kodlarda bir sorun mu var? yoksa ggogle bu
hizmeti durdurdu mu? Sadece boş bir... by ahmet
Programcı arkadaşların daha fazla takıldığı bir yerde
yazsa idiniz mesajınızı daha... by Tuğrul HELVACI
Sinan BARAN
Tuğrul Bey Yeri Burasımıdır Bilmiyorum O nedenle
hata ediyorsam özür dilerm bir iş ilanı... by geyikben
Teşekkürler ;) by Tuğrul HELVACI
Copyright © 2009 Delphi Programming
Pow ered by WordPress | Increase Traffic w ith TrafficWhirl.
PDFmyURL.com

Benzer belgeler

Class of …… | Delphi Programming

Class of …… | Delphi Programming Pointer GetCurrentProcess GetIconInfo GetKeyState

Detaylı

Her türlü veritipini kıyaslamak için.. | Delphi Programming

Her türlü veritipini kıyaslamak için.. | Delphi Programming kadar uğraşmaya..” Doğru haklısınız, peki o zaman örneklere devam edelim

Detaylı

İndirmek için tıklayın

İndirmek için tıklayın Window Station da neyin nesi ? Window Station kendine has bir clipboard’u olan, kendine has global atom tablosu olan, içinde birden fazla masaüstüne sahip olabilen; klavye, mouse ve ekran ile etkil...

Detaylı