ورود

View Full Version : شناسايي كليك ماوس در خارج از برنامه دلفي



FiACKER
پنج شنبه 23 مهر 1388, 01:56 صبح
سلام

همونطور كه از عنوانه تاپيك معلومه مي خوام مثلا وقتي كاربر در دسكتاپ كليك راست كرد ، برنامه ي من اين پيغام رو دريافت كنه.

اينو مي دونم كه با Hook بايد اين كار انجام بشه.

دوستاني كه در اين زمينه سورسي دارند لطف مي كنند اپلود كنن.

Asiapardaz
پنج شنبه 23 مهر 1388, 15:02 عصر
ببینید این کامپوننت جواب میده ؟!

FiACKER
پنج شنبه 23 مهر 1388, 15:20 عصر
من گفتم چطور كليك خارج از فرمه برنامه هاي دلفي رو شناسايي كنم !
نگفتم چطور كليك رو شبيه سازي كنم !

مثلا :
هر وقت يه جايي تويه ويندوز كليك راست شد يه پيغام نمايش داده بشه كه كاربر كليك راست كرد و هر وقت كاربر كليك چپ كرد بگه كه كليك چپ ماوس فشرده شده.

Asiapardaz
پنج شنبه 23 مهر 1388, 15:40 عصر
ببخشید از اینکه منظورتون رو درست متوجه نشدم

این هم اون چیزی که مشکل شما رو حل می کنه:
رمز فایل : www.asiapardaz.com (http://www.asiapardaz.com)

امر دیگه ای باشه در خدمتیم :قهقهه:

FiACKER
پنج شنبه 23 مهر 1388, 15:54 عصر
دوست عزيز مثله اينكه بازم متوجه نشديد :عصبانی++:

اگه كمي از فكره تبليغه سايتتون بيرون مي يومدين و به سوال من فكر مي كرديد دوباره پسته اسپم نمي زديد !!!!!
:متفکر:

Asiapardaz
پنج شنبه 23 مهر 1388, 16:16 عصر
دوست عزيز مثله اينكه بازم متوجه نشديد :عصبانی++:

اگه كمي از فكره تبليغه سايتتون بيرون مي يومدين و به سوال من فكر مي كرديد دوباره پسته اسپم نمي زديد !!!!!
:متفکر:


FiACKER عزیز نیت ما کمک به دوستان جهت حل مشکلاتشونه نه تبلیغ !
این کدهایی رو هم که گذاشتم فقط به این خاطر بود که ازشون کمک بگیری و مشکلت رو حل کنی ، به هر حال خودت هم باید یه کم تلاش بکنی .

انشاالله با کمک دوستان و سعی خودت مشکلت حل میشه .

یا علی ...

FiACKER
پنج شنبه 23 مهر 1388, 16:20 عصر
FiACKER عزیز نیت ما کمک به دوستان جهت حل مشکلاتشونه نه تبلیغ !
این کدهایی رو هم که گذاشتم فقط به این خاطر بود که ازشون کمک بگیری و مشکلت رو حل کنی ، به هر حال خودت هم باید یه کم تلاش بکنی .

انشاالله با کمک دوستان و سعی خودت مشکلت حل میشه .

یا علی ...

از شما ممنونم دوسته عزيز.
اما سورس هايي كه شما گذاشتيد رو من تست كردم. اولي براي شبيه سازي كليك بود و دومي هم مكانه جاريه ماوس رو پيدا مي كرد و ارتباطي با شناسايي كليك ماوس در خارج از برنامه را نداشت.

به هر حال ممنون

Mahmood_M
پنج شنبه 23 مهر 1388, 17:18 عصر
سلام
این هم یک مثال : لینک دانلود (http://nabegheh.parsaspace.com/Examples/Mouse_Hook.rar)

در این مثال از یک DLL به نام GetInput.dll استفاده شده که سورسش همراه مثال هست ، اگر نیاز به توضیح کدهای برنامه ی مثال بود ، بگید تا توضیح بدم ...

موفق باشید ...

FiACKER
جمعه 24 مهر 1388, 11:49 صبح
سلام
واقعا ممنون اقاي محمود
سورسي كه گذاشتيد خيلي كمكم كرد.
اين سورس رو خودتون نوشتيد ؟

يه سواله ديگه هم داشتم :


DLLProc := @EntryProc;
hMemFile := OpenFileMapping(FILE_MAP_WRITE, False, mapName);
if hMemFile <> 0 then
pFHandle := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);

اين كدها چه كاري رو انجام مي دهند در موقع اولين لود Dll ؟

FiACKER
جمعه 24 مهر 1388, 12:00 عصر
procedure EntryProc(Reason: Cardinal);
begin
if (Reason = Dll_Process_Detach) then
begin
CloseMap;
if Hooked then
begin
UnhookWindowsHookEx(hMseHook);
UnhookWindowsHookEx(hKeyHook);
end;
end;
end;
و اين EntryProc چطور ؟ براي چي هست ؟

آيا اين امكان وجود داره كه توابعي كه در برنامه ي اصلي من هست رو از DLL صدا بزنم ؟
يعني مثلا يه تابع در برنامه ي من وجود داشته باشه به نامه ABC و در DLL بتونم اين تابع رو صدا بزنم !؟

vcldeveloper
جمعه 24 مهر 1388, 21:20 عصر
اين كدها چه كاري رو انجام مي دهند در موقع اولين لود Dll ؟
من اون سورس رو دانلود نکردم، ولی این کدی که شما اینجا قرار دادید (در پست 9) یک Memory Map File را باز میکنه. استفاده از Memory Map File یکی از راه های اشتراک داده بین دو یا چند Process هست.


و اين EntryProc چطور ؟ براي چي هست ؟
در زمانی که یک DLL در فضای آدرس یک Process لود یا Unload میشه، یا توسط یک Thread مورد استفاده قرار میگیره، این EntryProc فراخوانی میشه، و پارامتری به آن پاس داده میشه که مشخص میکنه DLL در حال لود شدن یا Unload شدن هست. در کد بالا (پست شماره 10) اگر DLL توسط یک پروسس Unload بشه، هوک های ایجاد شده هم حذف میشند.


آيا اين امكان وجود داره كه توابعي كه در برنامه ي اصلي من هست رو از DLL صدا بزنم ؟
يعني مثلا يه تابع در برنامه ي من وجود داشته باشه به نامه ABC و در DLL بتونم اين تابع رو صدا بزنم !؟
بله، با استفاده از Call back function. به عنوان نمونه می تونید مستندات تابع EnumChildWindows ویندوز را مطالعه کنید. این تابع در داخل یکی از DLLهای ویندوز تعریف شده، و در زمان فراخوانی، آدرس یک تابع را از شما میگیره، و هر بار که پنجره ایی پیدا کرد، این تابع شما را فراخوانی میکنه.

Mahmood_M
جمعه 24 مهر 1388, 23:28 عصر
اين سورس رو خودتون نوشتيد ؟
نه من ننوشتم ...
در مورد سوال اول :

begin
DLLProc := @EntryProc;
hMemFile := OpenFileMapping(FILE_MAP_WRITE, False, mapName);
if hMemFile <> 0 then
pFHandle := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);

end.
همونطور که خودتون هم اشاره کردید ... ، این کدها در هنگام لود DLL اجرا می شن ...
DLLProc یک مقدار از نوع TDLLProc هست که در یونیت SysInit تعریف شده ، به زبان ساده DLLProc یک Procedure با امضایی به صورت " ;(MyProc(Reason : Integer " هست که در چند مرحله از طرف ویندوز فراخوانی میشه ، مثلا وقتی که یک پروسس یا یک Thread بخواد به DLL دسترسی داشته باشه ( مثلا اون رو لود کنه ... )
می تونید یک Procedure بنویسید مثل EntryProc در کد بالا و اون رو به این Procedure ربط بدید تا در زمان فراخوانی DLLProc توسط ویندوز اون Procedure اجرا بشه ...
در کد بالا و در قسمت " ;DLLProc := @EntryProc " هم همین اتفاق می افته ، یعنی DLLProc به آدرس حافظه ی Procedure ای با نام EntryProc اشاره میکنه و با فراخوانی DLLProc ، پروسجر EntryProc اجرا میشه ...
به عنوان یک مثال با استفاده از DLLProc میشه با توابعی مثل GetModuleFileName ، نام برنامه ی ای که DLL رو لود کرده رو پیدا کرد و ...
اما در مورد قسمت دوم کد :

hMemFile := OpenFileMapping(FILE_MAP_WRITE, False, mapName);
if hMemFile <> 0 then
pFHandle := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);
در مورد این که چرا این کدها اینجا اجرا میشن باید کل سورس رو بررسی کرد و جواب داد که اطلاعات اندک من امکان چنین چیزی رو به من نمی ده ، اما فقط در مورد FileMapping اگه بخوایم خیلی ساده بیان کنیم ، اجازه ی دسترسی مشترک دو برنامه به یک قسمت از حافظه رو می ده ( بهتره جستجویی در اینترنت در این مورد داشته باشید ... ! )

اما سئوال دوم :

procedure EntryProc(Reason: Cardinal);
begin
if (Reason = Dll_Process_Detach) then
begin
CloseMap;
if Hooked then
begin
UnhookWindowsHookEx(hMseHook);
UnhookWindowsHookEx(hKeyHook);
end;
end;
end;
Procedure بالا همونطور که توضیح داده شد ، به DLLProc نسبت داده میشه و در هنگام فراخوانی DLL اجرا میشه ... ، گفتیم این Procedure یک پارامتر داره به نام Reason ، همونطور که از نام Reason ( دلیل ! ) مشخص هست ، دلیل فراخوانی این Procedure رو مشخص میکنه ...
در کد بالا ابتدا چک میشه که دلیل فراخوانی این Procedure چی بوده ، اگر مقدار Reason برابر با Dll_Process_Detach بود ، یعنی اینکه یک برنامه که DLL رو Load کرده بود میخواد درواقع DLL رو UnLoad کنه !
خوب ، وقتی Detach شدن تشخیص داده شد ( Detach همون UnLoad که گفتم هست ! ) ، باید اون FileMapping بسته بشه ( اگه یادتون باشه در کد قبلی با OpenFileMapping یک FileMappingObject (http://www.Google.com) باز شده بود برای DLL ) که این کار با CloseMap انجام میشه ...
بعد از موارد بالا هم ، برنامه چک میکنه که آیا در حالت هوک هست یا نه که این هم به نویسنده ی سورس ربط داره ، مثلا در اینجا نویسنده از یک متغیر به نام Hooked برای تشخیص وضعیت هوک استفاده کرده ...
در نهایت اگر برنامه در حالت Hook بود ، با تابع UnhookWindowsHookEx به هوک پایان میده !!
در کد بالا این تابع 2 بار فراخوانی شده اولی برای UnHook کردن موس و دومی هم برای UnHook کردن صفحه کلید هست ...
توجه کنید که برای شروع هوک کردن از تابع SetWindowsHookEx استفاده شده :

{ for Keyboard }
hKeyHook := SetWindowsHookEx(WH_KEYBOARD, @KeyHookFunc, hInstance, 0);
{ for Mouse }
hMseHook := SetWindowsHookEx(WH_MOUSE, @MseHookFunc, hInstance, 0);
به زبان ساده این تابع به ویندوز اعلام میکنه که ارجاعات مربوط به پارامتر اول رو به آدرس تابع موجود در پارامتر دوم ارسال کنه ، مثلا در اولین خط کد و برای صفحه کلید پارامتر اول WH_KEYBOARD هست و پارامتر دوم KeyHookFunc@ که به فضای تابع KeyHookFunk در حافظه اشاره می کنه ...

توضیحات بنده با توجه به اطلاعات کمی که دارم شاید قابل استناد نباشه ، بهتره در این مورد جستجویی در اینترنت (http://www.Google.com) داشته باشید ...


ویرایش :
انگار جناب کشاورز زودتر پاسخ دادند ولی شاید این توضیحات هم به درد بخوره ...

موفق باشید ...

FiACKER
شنبه 25 مهر 1388, 22:30 عصر
واقعا نمي دونم چطور از زحماته آقاي كشاورز و محمود تشكر كنم كه وقت گذاشتند تا جواب بدند.
ممنون

براي دوستان كه اين بحث رو دنبال كردند :
Callback function ها چه هستند و چگونه در دلفی فراخوانی می شوند؟ (http://www.barnamenevis.org/forum/showthread.php?t=62794)

آقاي كشاورز لطفا فايلي كه ضميمه كردم (http://barnamenevis.org/forum/attachment.php?attachmentid=38509&stc=1&d=1255807044) رو مشاهده كنيد. اين فايل SDK يك پلاگين براي برنامه VB Decompiler هست كه فكر مي كنم براي ارتباط بيشتر و بهتر توابعي رو از برنامه اصلي صدا مي زند.

اگه زحمتي نيست در مورد كد زير كمي توضيح بديد. نظرتون رو هم در مورد ارتباط DLL با برنامه اصلي بگيد.

function SetValue(vlPluginEngine: pointer; vlType: integer; vlNumber: integer; vlFnNumber: integer; vlNewValue: pchar): pchar;
asm
push vlNewValue
push vlFnNumber
push vlNumber
push vlType
call vlPluginEngine;
mov result,eax
end;

دانلود برنامه VB Decompiler Lite - دانلود مستقيم (http://www.vb-decompiler.org/files/vb_decompiler_lite.zip)

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

محمود جان ممنون كه در مورد Reason توضيح دادي.
من سورس چند پلاگين رو كه ديدم در SDK به زبان سي كدهاي زير وجود داشت اما در SDK به زبان دلفي يك همچين كدهايي وجود نداشت. آيا دليلي داره ؟




BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

چرا اصلا يك همچين كدي رو در DLL هاي سي ++ وجود داره ؟

در حالي كه تمامي Case ها Break مي شوند !؟

vcldeveloper
یک شنبه 26 مهر 1388, 11:27 صبح
چرا اصلا يك همچين كدي رو در DLL هاي سي ++ وجود داره ؟

در حالي كه تمامي Case ها Break مي شوند !؟
به خاطر اینکه در دلفی بطور پیش فرض یک تابع DllMain برای شما تعریف شده، و اگر شما تابع جدیدی تعریف نکنید، دلفی از همان تابع پیش فرض خودش استفاده میکنه.



اگه زحمتي نيست در مورد كد زير كمي توضيح بديد. نظرتون رو هم در مورد ارتباط DLL با برنامه اصلي بگيد.
درباره چیش توضیح بدم؟ یک تابع دلفی هست که آدرس یک تابع رو به همراه آرگومان های آن تابع به عنوان ورودی میگیره، و با استفاده از کد اسمبلی، آرگومان ها را از راست به چپ در پشته قرار میده، تابع را فراخوانی میکنه، و مقدار برگشتی تابع را به عنوان مقدار برگشتی خودش برگشت میده.

Anis131313
جمعه 18 دی 1388, 11:37 صبح
لطفا دوستانی که این تاپیک رو همراهی میکردن یک سری هم به تاپیک زیر بزنن ممنون می شم چون سوال راجع به کد های همین برنامه است ...
ممنون :خجالت:

http://barnamenevis.org/forum/showthread.php?p=883788