1. مهمان گرامی، جهت ارسال پست، دانلود و سایر امکانات ویژه کاربران عضو، ثبت نام کنید.
    بستن اطلاعیه

چگونگي نوشتن قفل با وي بي

شروع موضوع توسط minaaa ‏3/9/13 در انجمن Visual Basic

  1. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,795
    تشکر شده:
    6,456
    امتیاز دستاورد:
    113
    قسمت 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. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,795
    تشکر شده:
    6,456
    امتیاز دستاورد:
    113
    پاسخ : چگونگي نوشتن قفل با وي بي

    قسمت 2

    حالا فرض كنيم كه اين اتفاق افتاد يعني اينكه برنامه معلق شد .چيكار بايد بكنيم
    فرض كنيم كه نقطه شروع برنامه ما در حافظه 401000 باشه ودر افست ( بيت ) 0x445B كد برنامه ( به هگزه ) و شامل اطلاعات
    کد:

    E9XXXXXXXX
    كه يعني به نقطه اي از حافظه بپر .
    خوب ما اين كد رو با يه برنامه ( يك هگزه اديتور و يا برنامه اي كه مي شه نوشت ) به مقادير کد:

    EBFE9090C0
    تغيير ميديم
    خوب EB يعني پرش از نوع نزديك حداكثر مقدار پرش 128 تا جلو يا 127 تا عقب
    عدد بعدي يعني : مقداربايتي كه بايد بپره (از بايت بعدي ) رو معين مي كنه در اين حالت خاص چون عدد ما بيشتر از 128 پس پرش ما منفي شده يعني برگشت به عقب كه اينطوري حساب ميشه:
    مقدار كنوني(0) منهاي مقداري كه بايد بپره يعني 2 تا عقب ( برگرده به اول دستور خودش) ميشه FE ( هر پرش نزديك دو بايت ميگيره يكي دستور EB و مقدار پرش )
    بعد 90 كه يعني nop يعني هيچ كاري نكن و بگذر ( no oprate)
    بعدش دوباره 90
    و بعدش C0 يعني Ret خروج از برنامه ( چون هيچ الوكيت نشده پس احتياج به استفاده كردن از تابع Exitprocess و از اين دست توابع نداريم )
    خوب اگه كسي اين برنامه رو كه ما تغيير داديم اجرا كنه چي ميشه :
    هيچي يا ويندوزش هنگ ميكونه ( خيلي خيلي كند ميشه ) و برنامه تو حافظه ميمونه ( رجيستر ميشه ) و بايد يه جوري از حافظه اونرو پاك كنه
    و يا اينكه از برنامه خارج ميشه ( يعني به طريقي به كد C0 ميرسه ).
    نكته براي اطمينان بيشتر ميشه كدهاي بيشتري رو برداشت يعني منظورم از ابتدا كد هاست كه درون برنامه قرار داره ( برنامه اي كه مي خوايم روش قفل بگذاريم ) و در نتيجه يه ذره كار ها بيشتر ميشه و ميشه حفاظت رو بيشتر كرد .

    حالا ما بايد به عنوان برنامه نويس يه لودربراي اين برنامه تحت ويندوز بسازيم و بعد از لود كامل فايل اجراي اون رو تغيير بديم و به كد اصلي برگردونيم تا برنامه درست عمل كنه مثل يه پكر ​
     
  3. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,795
    تشکر شده:
    6,456
    امتیاز دستاورد:
    113
    پاسخ : چگونگي نوشتن قفل با وي بي

    چگونگي نوشتن قفل با وي بي

    خوب براي مثال ما يه برنامه واقعي مثل 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​
    ست كردن اين نوع برنامه ها رو همه بلدن[​IMG]
    توي قسمت توضيحات اين كدها رو اضافه مي كنيم:
    کد:

    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 ​
     
  4. کاربر پیشرفته

    تاریخ عضویت:
    ‏9/12/10
    ارسال ها:
    19,795
    تشکر شده:
    6,456
    امتیاز دستاورد:
    113
    پاسخ : چگونگي نوشتن قفل با وي بي

    حالا مي خوايم يه تغييرات بديم توي فايل 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 استفاده نميكنه نمي تونه رو اين تابع به راحتي بريك پوينت قرار بده و....
     
  5. عضو جدید

    تاریخ عضویت:
    ‏17/12/17
    ارسال ها:
    3
    تشکر شده:
    6
    امتیاز دستاورد:
    3
    مطالبتون خیلی خیلی خوبه ممنونم مرسی
     
    AftabGardoon از این پست تشکر کرده است.