找call!

先說下call是什麼。
call就是程序調用。熟悉VB的朋友,應該熟悉調用函數call add(a, b)的方法。
在任何程序的編寫中都有很多call。如何找到正確的call是比較難的事情。
列一個調用過程:
call 鼠標點擊
{
     call 判斷是點到怪、物品、地面
     {
        select
        case 怪 : call 選怪
        case 物品 : call 撿取物品
        case 地面 : call 走路
        case 牆壁 : call ...
        case ...
     }
}
call 選怪(怪物ID或標識)
{
     push 明文包
     call 加密
}
call 撿取物品(物品ID或標識)
{
     push 明文包
     call 加密
}
call 加密1級
{
     call 加密n級
     {
         w32_send()
         //發送給服務器
     }
}
遊戲的大概流程就是這樣子的了。
對於找call來說,重要的是在n層嵌套中找到正確的call。這方面只能靠經驗或猜測,看那個
push比較有戲。具體的方法也很簡單,在N層嵌套的call中,看那個參數我們比較熟悉,比如觀
察是否有怪物ID等。在多個call中找到一個我們熟悉的,然後調用,觀看效果,如果不對,再試
別的。
上次講過,在找周圍怪物列表的時候,通過call 選怪(怪物ID或標識),向上跟蹤找到怪物ID的
來源。這個怪物ID肯定是在周圍所有怪物中的其中一個,所以通過這種方法,可以找到怪物周圍
列表。
基本的原理和方法都已經講出來了。對於初次找CALL的朋友,可能對操作系統和編譯器生成的原
理不是很熟悉。我這裏大概說一下,也是重點。
首先要明白,windows是多進程、多線程的操作系統。CPU輪流切換時間片給每個線程。而每個進
程都有自己獨立的地址空間。具個例子,一排的牢房,CPU是送餐的,從左到右一直送過去。
每個牢房都是獨立的,不會影響其他的牢房。
而DOS操作系統是單進程的,每次只能運行一個程序。這裏我要說的是,當你面對一個進程的時
候,就不要考慮其他進程怎麼樣怎麼樣了,因爲其他的進程和你自己的進程是沒有關係的。這也
是在大學裏講c或者彙編只考慮一個進程的原因。
我們繼續。
而在一個進程裏的多個線程是共享當前進程空間的,如果你寫過多線程的程序,就比較容易理解
call是怎麼回事。我們看代碼:
function add(a, b) as long
{
    add = a + b
}
這是一個加法的call。
在我們的程序裏有2個線程。
function thread1()
{
     while 1
     {
        text1 = add(1, 2)
     }
}
function thread2()
{
      while 1
      {
         text2 = add(2, 3)
      }
}
2個線程都可以調用add函數,都可以得到正確的結果。同樣的概念套到遊戲裏就是遊戲的線程和
我們自己的線程都可以調用“選怪”這個函數,並且得到正確的結果。call的原理就是讓我們自
己的程序,去調用遊戲裏的函數。當然,必須存在我們這個“線程”。注意,這裏線程是非常關
鍵的。如果不是一個新的線程,就無法得到CPU時間片。所以,一定是一個線程在調用1個或者多
個call。
明白概念之後,我們就可以考試動手了。首先找到call的地址,然後想辦法調用他。
這裏又需要考慮,我們如何才能調用它。首先第一個概念是要在遊戲進程開闢一個線程,在這個
線程中做我們想要的操作。
那麼首先要做的是,把這個線程放在遊戲進程中。目前流行的方式有2中,編寫鉤子dll。或者遠
程注入一個dll。
因爲dll沒有自己的獨立空間,只能依附在一個exe的進程當中。而且windows幫我做了很多dll在
exe空間中定位的問題。所以dll就是我們的不二選擇。
鑑於鉤子和遠線程的資料非常多,我就不寫了。
我習慣用遠線程來注入dll。按我的習慣,我們繼續說。
被注入的dll,一定要是個標準dll。不能是activex dll。兩者的調用方式不同,所以不能用
activex,這也決定了vb做的dll是不能被注入的。能被注入遊戲地址空間中的dll,幾乎都是用c
或者delphi寫的。所以這個dll,還需要大家去學習這兩種語言中的一種。
然後在dll裏,直接調用。比如我們找到的call彙編如下:
push 1
push 2
call 123456
這裏傳遞1和2做加法操作。我們在自己的dll寫下:
__asm
{
     push 2
     push 5
     call 123456
}
這樣,這個call中就實現了2+5的操作。如果在123456這個call中,輸出一個和的消息框,我們
就能看到結果了。在後面我會給出一個可操作的exe和注入dll的代碼。
我要說的最後一個概念,也是很多人的疑問。已經注入的dll,我們如何調用它。
可以很明確的告訴你,不能調用(其實也不是不能調用,只是很麻煩,也非常佔用資源,就是利
用遠線程調用)。因爲你的dll已經生存在對方進程中了。你自己的exe又是另外一個獨立的進程
。想像一下,如果你能調用對方進程裏dll中的函數,那不是也可以直接調用遊戲call了麼:)
這樣的話,也就不需要注入了。
然後你肯定又會問,如果不能調用dll裏的函數,我們讓他執行。
這裏有2種方法,
1.全部代碼都在dll中寫,包括界面、流程等這些內容。
2.採用進程間交互的方法。windows雖然不同意你調用其他進程中的數據,但是允許不同的進程
間做數據通訊。進程間通訊的方法很多,比如消息,共享內存區,映射文件等。百度上資料很多

如果有朋友用過readProcessMemory API的話,一定會奇怪,我們可以讀寫其他進程中的函數,
爲什麼你又說windows不允許呢。如果你有跟蹤過readProcessMemory函數的話,你會發現,該
API用的是共享內存區的方式獲得對方內存中的數據。
就先寫這麼多吧,打這麼點字也用了半個多小時。
- 幻覺公式 2007.06.19 13:29
歡迎轉載,但請保留所有內容。
也歡迎朋友們,接着這個話題繼續說下去,或者對未說明的地方進行補充。 
發佈了5 篇原創文章 · 獲贊 2 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章