قسمت 1 ايا شما با برنامه tzcopy كار كرديد يا نه. يه برنامه است براي تغيير iso و سپس قرار دادن يه لودر براي فايل exeكه اگه فايل قفل با سايز مشخص رو سي دي نبود اون فايل اجرايي اجرا نشه و.... اين برنامه رو با وي بي نوشتن چون به runtime dll msvb... نيازمنده. پرتكتور اين برنامه مياد يه فايل exe درست ميكنه و بعد از فايل شما رو به پسوند .dat ذخيره كرده و..... ولي اين كار يه باگ داره اونم اينه كه اگه يكي بياد و فايل با پسوند dat رو تغيير پسوند به exe بده فايل اجرا ميشه حالا ما ميخواييم همچين كاري رو يكنيم ولي يه زره پيشرفته تر يعني اگه حتي فايل dat رو به exe تغيير داد اجرا نشه يعني در كل فايل exe مون رو پچ نيم و يه پچر براش بنويسيم براي اجرا يه برنامه توسط وي بي فرماني هست به نام shell كه فايل رو اجرا كرده و بعد از اجرا فايل بر اساس تنظيمات ما سكان كشتي رو يا در اختيار فايل ميزاره و يا به برنامه ما . يه راه حل ديگه استفاده از api ويندوز : کد: Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long ويا Declare Function ShellExecuteEx Lib "shell32.dll" Alias "ShellExecuteEx" (SEI As SHELLEXECUTEINFO) As Long مثلا ShellExecute Me.hwnd, vbNullString, "pi.net", vbNullString, "C:\", SW_SHOWNORMAL خوب براي اينكه بتونيم اخيتار كامل رو در دست بگيريم بايد ببينيم اين تابع چي كار ميكنه يا اصلا چه جوري يه فايل اجرايي احرا ميشه. 1-اول از همه لودر ويندوز مياد چك ميكنه كه ايا هدر فايل اگزه درست يا نه اگه نه كه يه خطا گزارش ميكنه 2-اگه فايل dll داشت ( كه اگه تحت ويندوز باشه صد در صد داره) ميبينه كه چه dll رو بايد استفاده كنه كه اين اطلاعات هم باز توي هدر فايل اگزه است . 3-بعد از اون تمامي توابع api رو بر اساس نوع فايل اگزه مشخص و ادرس دهي ميكنه 4-بعد مياد تمامي سكشنها رو براساس اين هدر توي حافظه لود ميكنه( وتمامي ريسورسها رو ) 5-سكشن اجرايي رو براساس خصوصيات اون سكشن با خاصيت WRC لود كرده و تمامي كالها به api رو مقدار دهي ميكنه 6-بعد از اون تمامي Call هاي برنامه رو اگه ديناميك بود متغيير دهي كرده و كد رو اماده اجرا ميكنه 8-EPO رو براساس هدر معين كرده وسپس مياد نوع اجرا رو معين كرده 9-حالا با ست كردن ريجستر ,esp,ebx,eds,EPI اختيار برنامه اجرايي رو بدستش ميده اين EPO =Entry point يا نقطه شروع كد.كه ما باهاش كار داريم( ممكنه يه لودر كار هاي ديگه اي هم بكنه ولي تا اونجا كه يادم بود سعي كردم همه چيز رو بنويسم و ممكنه توي ترتيب مراحل وسطي اشتباه كرده باشم ولي مهم فهم چگونگي اجراست ولي مرحه 9 هميشه اخر همه هست) بر اساس اين اطلاعات ميشه ديد كه اگه به لودر بگيم (دستور بديم) مرحله 9 رو اجرا نكن چي ميشه هيچي فايل اجرايي ما اجرا نيمشه و به حالت معلق در مياد (suspended ) و ما حالا مي تونيم چك كنيم و .... ادامه دارد
پاسخ : چگونگي نوشتن قفل با وي بي قسمت 2 حالا فرض كنيم كه اين اتفاق افتاد يعني اينكه برنامه معلق شد .چيكار بايد بكنيم فرض كنيم كه نقطه شروع برنامه ما در حافظه 401000 باشه ودر افست ( بيت ) 0x445B كد برنامه ( به هگزه ) و شامل اطلاعات کد: E9XXXXXXXX كه يعني به نقطه اي از حافظه بپر . خوب ما اين كد رو با يه برنامه ( يك هگزه اديتور و يا برنامه اي كه مي شه نوشت ) به مقادير کد: EBFE9090C0 تغيير ميديم خوب EB يعني پرش از نوع نزديك حداكثر مقدار پرش 128 تا جلو يا 127 تا عقب عدد بعدي يعني : مقداربايتي كه بايد بپره (از بايت بعدي ) رو معين مي كنه در اين حالت خاص چون عدد ما بيشتر از 128 پس پرش ما منفي شده يعني برگشت به عقب كه اينطوري حساب ميشه: مقدار كنوني(0) منهاي مقداري كه بايد بپره يعني 2 تا عقب ( برگرده به اول دستور خودش) ميشه FE ( هر پرش نزديك دو بايت ميگيره يكي دستور EB و مقدار پرش ) بعد 90 كه يعني nop يعني هيچ كاري نكن و بگذر ( no oprate) بعدش دوباره 90 و بعدش C0 يعني Ret خروج از برنامه ( چون هيچ الوكيت نشده پس احتياج به استفاده كردن از تابع Exitprocess و از اين دست توابع نداريم ) خوب اگه كسي اين برنامه رو كه ما تغيير داديم اجرا كنه چي ميشه : هيچي يا ويندوزش هنگ ميكونه ( خيلي خيلي كند ميشه ) و برنامه تو حافظه ميمونه ( رجيستر ميشه ) و بايد يه جوري از حافظه اونرو پاك كنه و يا اينكه از برنامه خارج ميشه ( يعني به طريقي به كد C0 ميرسه ). نكته براي اطمينان بيشتر ميشه كدهاي بيشتري رو برداشت يعني منظورم از ابتدا كد هاست كه درون برنامه قرار داره ( برنامه اي كه مي خوايم روش قفل بگذاريم ) و در نتيجه يه ذره كار ها بيشتر ميشه و ميشه حفاظت رو بيشتر كرد . حالا ما بايد به عنوان برنامه نويس يه لودربراي اين برنامه تحت ويندوز بسازيم و بعد از لود كامل فايل اجراي اون رو تغيير بديم و به كد اصلي برگردونيم تا برنامه درست عمل كنه مثل يه پكر
پاسخ : چگونگي نوشتن قفل با وي بي چگونگي نوشتن قفل با وي بي خوب براي مثال ما يه برنامه واقعي مثل Notepad.exe رو قفل مي كنيم .( ورژن اين برنامه 5.1.2600.2180 متعلق به ويندوز xp) براي اين كار فايل notepad.exe رو توي به فولدر مثل work كپي ميكنيم حالا با يه برنامه كه اطلاعات هدر فايل exe رو نشون ميده برنامه notepad رو مورد بررسي قرار ميديم ( مثل برنامه ProcDump32 توي قسمت PE Editor) *نكته تمامي عددها در مبناي hex مي باشد Entry Point : 739d Size of image:14000 Image Base: 01000000يعني EP ما در حافظه برابر است با EP=01000000+739d=0100739dو در قسمت سكشنها داريم: کد: .text Virtual Size:00007748 مقدار فضايي كه اين سكشن در حافظه ميگيره Virtual Offset:00001000 ( Image base محل شروع در حافظه(بعلاوه RAW Size:00007748 مقدار فضايي كه اين سكشن در روي هارد ميگيره Raw Offset:00000600 محل شروع در روي هارد Characteristics:60000020 خصوصيت اين سكشن مثل خواندن و توشتني و .... .data Virtual Size:00001BA8 مقدار فضايي كه اين سكشن در حافظه ميگيره .... .rsrc Virtual Size:00008958 مقدار فضايي كه اين سكشن در حافظه ميگيره .... همانطور كه ديده ميشه EP برنامه ما درون سكشن .text پس محل شروع برنامه بروي هارد ميشه: REP:739d-1000+600=699dحالا با يه برنامه هگزه اديتور اگه به اين محل پرش كنيم : 6A706898180001 كه يعني : 6A70 push 00000070 6898180001 push 01001898حالا ما خط اول رو با اين كد عوض مي كنيم ( موقعيت 699d از اول فايل ) EBFE كه قبلا توضيح دادم يعني چيو برنامه رو به اسم test.lck ذخيره مي كنيم . حالا اگه فايل رو اجرا بكنيم مي بينيم كه فايل اجرا نميشه ( براي اجرا اون بايد با پسوند Exe ذخيرش كنيم ( . حالا بايد برنامه اي با وي بي بنويسيم كه بياد و اين كد رو يعيني EBFE رو با 6A70 عوض كنه . برنامه Microsoft Visual Basic رو ران كرده و يه پروژه جديد از نوع STANDARD EXE مي سازيم و بعد فرم پيش فرض وي بي رو حذف كرده و يك Module به برنامه اضافه مي كنيم . براي اينكه برنامه مون اجرا بشه احتياج به Public Sub Main() End Subست كردن اين نوع برنامه ها رو همه بلدن توي قسمت توضيحات اين كدها رو اضافه مي كنيم: کد: Option Explicit Dim lngProcess As Long Dim lngThread As Long Dim lngProcessID As Long Dim lngThreadID As Long Dim lngReply As Long Public Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Byte hStdInput As Long hStdOutput As Long hStdError As Long End Type Public Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Long dwThreadId As Long End Type Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess _ As Long, ByVal uExitCode As Long) As Long Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As _ Long) As Long Public Declare Function WaitForSingleObject Lib "kernel32" _ (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Public Declare Function CreateProcess Lib "kernel32" Alias _ "CreateProcessA" (ByVal lpApplicationName As String, ByVal _ lpCommandLine As String, lpProcessAttributes As Any, _ lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal _ dwCreationFlags As Any, lpEnvironment As Any, ByVal _ lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As Long Public Declare Function GetWindowThreadProcessId& Lib "user32" _ (ByVal hWnd As Long, lpdwProcessID As Long) Public Declare Function ResumeThread Lib "kernel32" _ (ByVal hThread As Long) As Long Public Declare Function WriteProcessMemory Lib "kernel32" _ (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, _ ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long Public Const GW_HWNDNEXT = 2 Public Const WM_QUIT = &H12 Public Const WM_CLOSE = &H10 Public Const SYNCHRONIZE = &H100000 Public Const NORMAL_PRIORITY_CLASS = &H20& Public Const CREATE_SUSPENDED = &H4& Public pInfo As PROCESS_INFORMATION Public sInfo As STARTUPINFO Public sNull As String و بعد توي سابروتين main اين كدها رو اضافه مي كنيم کد: Public Sub Main() Dim txtStart As String, pHandle As Long, BufferTXT As String ' اسم برنامه ما كه مي خواييم با تابع زير اون رو اجرا كنيم txtStart = "test.lck" ' چك كردن وجود فايل در زير شاخه اجرا برنامه If Dir(txtStart) = "" Then MsgBox "Failed to Start " End End If 'مقدار دهي متغييري كه مشخصات برنامه ما رو مثل دستگيره برنامه رو نگه ميداره sInfo.cb = Len(sInfo) ' اجرا برنامه بوسيله تابع CreateProcess با خاصيت Suspended كه باعث ميشه برنامه بصورت معلق اجرا بشه و هنگامي كه لودر به EP رسيد برنامه ' متوقف بشه و منتظر فرمانResumeThread بشه كه برنامه اجرا بشه در اين صورت ميشه هر موقعه بخواييم برنامه رو متوقف و يا ادامه دهيم lngReply = CreateProcess(sNull, txtStart, ByVal 0&, ByVal 0&, 1&, _ CREATE_SUSPENDED, ByVal 0&, sNull, sInfo, pInfo) ' چك ميكنه ايا برنامه اجرا شد يا نه ؟ If lngReply = 0 Then MsgBox "Unable to start " End End If 'ذخيره اطلاعات اوليه برنامه براي استفاده هاي بعدي lngProcessID = pInfo.dwProcessId lngThreadID = pInfo.dwThreadId lngProcess = pInfo.hProcess lngThread = pInfo.hThread '6A70 مقدار دهي بافري كه بايد نوشته بشه يعني مقدار BufferTXT = Chr(&H6A) & Chr(&H70) ' نوشتن در حافظه برنامه ( ِD100739 ) توسط تابع WriteProcessMemory lngReply = WriteProcessMemory(lngProcess, &H100739D, BufferTXT, Len(BufferTXT), 0&) ' چك كردن اينكه نوشتن با موفقيت انجام شده يا نه و گرنه به تابع اتمام برنامه برو If lngReply = 0 Then MsgBox "Failed to change. " GoTo End_Process End If ' ادامه دادن برنامه ( تمامي تغييرات اعمال شده و مثل فايل اوليه شده اما در حافظه ) lngReply = ResumeThread(lngThread) ' چك كردن ادامه برنامه و در صورت عدم ادامه برنامه پرش به قسمت اتمام برنامه If lngReply = 0 Then MsgBox "Failed to Resume " GoTo End_Process End If ' بستن هندلهاي استفاده شده lngReply = CloseHandle(lngThread) lngReply = CloseHandle(lngProcess) ' خروج از برنامه End End_Process: ' اتمام برنامه lngReply = TerminateProcess(lngProcess, 0&) ' بستن هندلهاي استفاده شده lngReply = CloseHandle(lngThread) lngReply = CloseHandle(lngProcess) ' خروج از برنامه End End Sub
پاسخ : چگونگي نوشتن قفل با وي بي حالا مي خوايم يه تغييرات بديم توي فايل exe تا اونو نشه براحتي شناخت كه با وي بي نوشته شده. اول بايد فايل اجرايي رو طوري تغيير بديم كه نشانه هاي وي بي حذف بشه . اولين مشكل msvb ران تايم dll .خوب همه ميدونن كه براي اجراي فايل اي كه با وي بي نوشته شده احتياج به اين dll هستش . خوب ابتدا ما برنامه اجرايي رو با يك هگزا اديتور بازش مي كنيم و بعد دنبال msvbvm60.dll ( براي وي بي 6) مي گرديم و اونرو به testtest.tst تغيير مي ديم و برنامه رو ذخيره كرده و بعد اجرا مي كنيم . سيستم ارور ميده كه اين فايل رو پيدا نكرده. testtest.tst . براي اينكه فايل اجرا بشه از msvbvm60.dll يه نسخه توي جاي كه فايل اجراي هست كپي كرده و بعد اون رو به نام testtest.tst تغيير نام مي ديم و حالا برنامه رو اجرا مي كنيم. بينگو اجرا شد. با اين ترفند ميشه همه توايع موجود توي فايل رو كه با vba شروع ميشن رو تغيير نام داد . ( بايد هر اسمي كه براي اون تابع مشخص ميكنيم توي فايل اجرايي توي فايل testtest.tst هم همون اسم رو براش بذاريم) بعضي از توابع هم با rtc شروع ميشن مثلا rtcMidBstr كه همون تابع mid است. خوب با يك مثال فكر كنم قضيه روشن تر بشه: همون rtcMidBstr رو دنظر بگيريم اگه اين تابع رو به توي فايل اجرايي به ord0000001 تغيير نام بديم بايد توي فايل testtest.tst هم به همين نام تغييرش بديم .لذا هنگامي كه فايل اجرايي لود ميشه لودر توي هدر فايل testtest.tst دنبال محل شروع ord0000001 ميگرده و اگه ما توي اين فايل اين rtcMidBstr عوض نكرده باشيم به ما صفحه خطا رو نشون ميده. حالا بر اساس اين توضيحات ميشه يه فايل نوشت كه دقيقا اين كار رو بكنه و بعد فايل testtest.tst رو با يك برنامه exepacker پك كرد و درنتيجه كركر ها گمراه ميشن . چون يكي از كارهاي كه كركر ها ميكنن قرار دادن بريك پوينت روي تابع مقايسه است ( بطور مثال براي مقايسه دو عبارت رشته اي وي بي معمولا از تابع vbaStrTextCmp __ استفاده ميكنه) حالا اگه كركر سر فصل فايل msvbvm60.dll رو توي ديباگرش لود كنه چون برنامه ما از فايل اصلي msvbvm60.dll استفاده نميكنه نمي تونه رو اين تابع به راحتي بريك پوينت قرار بده و....