天天看點

網頁網遊的外挂實作與分析 之 開心網外挂實作一.分析 二.實作

        關于網頁網遊大家應該已經有所感受了。現在最火的莫過于kaixin001的種菜養動物了。大家偷菜種菜樂此不疲。不過怎麼才能自動的進行偷菜呢?我自己簡單的分析了一下,并實作了一個kaixin001菜地殺手。一下簡述了從分析到開發的整個過程。雖然沒有将所有代碼都分享出來,但是下邊的分析足夠大家寫一個類似的程式了。大家可以去http://orion.zhangle.googlepages.com 來下載下傳這個程式。

一.分析

       我們知道其實網頁網遊無非就是通過網頁和伺服器端得各種規則來實作的一種簡單的網絡遊戲。這種遊戲因為SNS的風靡而變得火熱。但是雖然它是網遊。但是本質上還是一個網頁,通過超連結,圖檔,javascript來實作各種頁面的跳轉和資料的傳輸。是以說本質上他跟一個傳統的網頁沒有本質上的差別。隻是各家的網遊有着不同複雜程度的網頁而已。

       我們這次首先找到一個簡單的網頁網遊進行分析。例如,kaixin001的種菜遊戲。這個種菜遊戲大家都知道其表示形式是一個Flash,跟網頁有着本質的不同。但是其手機版确實是一個非常普通的wap網站通過WML描述語言實作的。我們就從這裡進行的入手。

      1.登入

        WAP網站不僅可以通過手機登陸,通過電腦的WEB浏覽器同樣能夠登入,因為他仍然通過HTTP協定進行資料的交換。當然IE目前不支援這種行為,不過google 的chrome可以支援WAP網站的浏覽。我們通過Chrome登入http://wap.kaixin001.com。我們可以看到其登入換面如下。

網頁網遊的外挂實作與分析 之 開心網外挂實作一.分析 二.實作

    可是我們如何通過程式登入呢?這裡我們需要檢視一下這個wap頁面的源代碼。

<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>手機開心網</title>

</head>

<body>

<div>

<img src="http://wapimg.kaixin001.com.cn/wapi2/logo4.gif" mce_src="http://wapimg.kaixin001.com.cn/wapi2/logo4.gif" width="120" height="36"

title="開心網" /></div>

<div id="info">

通過開心網,您可以與朋友保持聯系,分享你的生活和快樂。</div>

<div id="login_area">

<form method="post" action="/home/">

<span>賬号(電子郵件):</span><p>

<input name="email" type="text" size="10" value="" class="ipt"

maxlength="200" /></p>

<span>密碼(區分大小寫):</span><p>

<input name="password" type="password" value="" class="ipt" maxlength="200" size="10" /></p>

<p>

<input name="remember" type="checkbox" value="1" checked="true" />自動為我登入</p>

<input name="from" type="hidden" value="" /><p>

<input name="login" type="submit" value=" 登 錄 " class="rb" /></p>

</form>

<a href="http://wml.kaixin001.com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" mce_href="http://wml.kaixin001.com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >舊版開心網入口</a><br />

<p>

還沒有加入開心網?請用電腦上www.kaixin001.com注冊。</p>

</div>

<div id="bottom">

<a href="/common/help.php?index=1" target="_blank" rel="external nofollow" mce_href="common/help.php?index=1" target="_blank" rel="external nofollow" class="tdno">幫助</a> <a href="/feedback/feedback.php?index=1" target="_blank" rel="external nofollow" mce_href="feedback/feedback.php?index=1" target="_blank" rel="external nofollow"

class="tdno">回報</a><br />

10-15 10:42<br />

©開心網 2009

</div>

</body>

</html>

通過代碼我們發現我們隻需要填寫相應的表單即可登入網站。這裡需要填寫的是在<div id="login_area">這個标簽中的表單。 表單項有

email(用于确定使用者名)

password(密碼)

remember(是否自動登入)

from(暫且不知,而且還是個隐藏項,但是沒有指派,我們暫且不理睬)

login(登入按鈕值為“ 登  錄 ”,注意裡邊的空格)

表單的action為/home/

這個表單的具體表項我們先記錄下來,已備後用。

這裡我們還發現了一個網頁的特征就是網頁使用UTF-8進行字元的編碼,這個也是之後我們要注意的事情。

    2.登陸後的頁面分析

    其實登陸後的目的很簡單,我們就是為了找到農場的的連結在哪然後開始偷菜。我們知道通過wap去農場的步驟就是一路點選[元件]->[買房子]->[花園菜地]->[可偷的菜地]。也許大家發現直接找到可以偷的菜地這個連結就可以了。其實不然。各種網站都有了防機器人放外挂的方式。一般都是引入了一些系統生成的驗證資料。别看wap版本的開心001,它仍然引入了這些機制。我們通過登入後的代碼片段可以進行檢視。可以看到每個超連結基本上都要發送一個verify變量。你每次重新整理一次頁面verify變量都會改變。經過試驗如果你發送的veryify變量不是它系統生成的導緻的結果就是被系統強制登出登入。是以我們需要老老實實的逐一連結的進入需要的網址。

<div id="nav">

<a href="/home/?uid=696485&verify=696485_696485_1255578105_6c2a9135bc0803cbcb6e77be0794b643_kx" target="_blank" rel="external nofollow" mce_href="home/?uid=696485&verify=696485_696485_1255578105_6c2a9135bc0803cbcb6e77be0794b643_kx" target="_blank" rel="external nofollow" class="tdno">首頁</a>

<font color="#666666">|</font>

<a href="/friend/?uid=696485&verify=696485_696485_1255578105_6c2a9135bc0803cbcb6e77be0794b643_kx" target="_blank" rel="external nofollow" mce_href="friend/?uid=696485&verify=696485_696485_1255578105_6c2a9135bc0803cbcb6e77be0794b643_kx" target="_blank" rel="external nofollow" class="tdno">好友</a>

<font color="#666666">|</font>

<a href="/msg/?verify=696485_696485_1255578105_6c2a9135bc0803cbcb6e77be0794b643_kx" target="_blank" rel="external nofollow" mce_href="msg/?verify=696485_696485_1255578105_6c2a9135bc0803cbcb6e77be0794b643_kx" target="_blank" rel="external nofollow" class="tdno">消息</a>

<font color="#666666">|</font>

<a href="/home/news.php?uid=696485&verify=696485_696485_1255578105_6c2a9135bc0803cbcb6e77be0794b643_kx" target="_blank" rel="external nofollow" mce_href="home/news.php?uid=696485&verify=696485_696485_1255578105_6c2a9135bc0803cbcb6e77be0794b643_kx" target="_blank" rel="external nofollow" class="tdno">動态</a>

<font color="#666666">|</font>

<a href="/app/mylist.php?verify=696485_696485_1255578105_6c2a9135bc0803cbcb6e77be0794b643_kx" target="_blank" rel="external nofollow" mce_href="app/mylist.php?verify=696485_696485_1255578105_6c2a9135bc0803cbcb6e77be0794b643_kx" target="_blank" rel="external nofollow" class="tdno">元件</a>

</div>

    當我們一步步通過連接配接進入到了[可以偷的菜地]後我們需要看看這個頁面都有什麼特征了。在這個頁面我們發現裡邊都是好友的名字的連結。隻有進入了好友的名字的連結才能夠【偷菜】。我們先不進去,我們先來看看我們怎麼知道都有哪些好友。好友頁面被系統分頁了,是以我們需要知道目前是不是好友頁面的最後一頁。這個特征比較好找到。當隻有【下一頁】這個連結的時候說明好友頁面還沒有到最後一頁。當【下一頁】和【上一頁】這兩個連結都出現也說明沒有到頭。隻有出現了隻有【上一頁】這個連結的時候才算是好友頁面到頭了。還有一個特殊情況,就是你的好友實在是太少,根本沒有【上一頁】和【下一頁】這兩個連結,這個也可以算是好友頁面到頭了。

3.偷菜的連結

    下邊我們進入好友的名字的那個連接配接。進入後我們發現我們已經進入了好友的菜地中。裡邊的網頁大緻上是這個樣子的。

網頁網遊的外挂實作與分析 之 開心網外挂實作一.分析 二.實作

      分析下邊的代碼我們發現,所有可以偷的菜的資訊都包含在了一個有【偷】這個連結的<div>标簽中。标簽中還包括了可偷的物品的名字,還剩多少可以偷。以及【偷】這個連結。在這裡我們再次見識到了Veryfiy這個變量,看來驗證資訊無處不在,大意不得。

<div class="list">

牧草:<font color="#336600">剩餘43</font><br />

<span class="c9"></span>

<a class="a2" href="/house/garden/havest.php?verify=696485_696485_1255582764_506bb5ad61fbaae16152bb77a520eeda_kx&

farmnum=5&fuid=16781289&url=%2Fhouse%2Fgarden%2F%3Fverify%3D696485_696485_1255582760_2aecce2df49bd03ea6cab9aae

f1b7899_kx%26fuid%3D16781289%26url%3D%252Fhouse%252Fgarden%252Fgetfriendmature.php%253Fverify%253D696485_696485_1255582756_5fd523cb95f5f90dfa81845212241b6e_kx" mce_href="house/garden/havest.php?verify=696485_696485_1255582764_506bb5ad61fbaae16152bb77a520eeda_kx& farmnum=5&fuid=16781289&url=%2Fhouse%2Fgarden%2F%3Fverify%3D696485_696485_1255582760_2aecce2df49bd03ea6cab9aae f1b7899_kx%26fuid%3D16781289%26url%3D%252Fhouse%252Fgarden%252Fgetfriendmature.php%253Fverify%253D696485_696485_1255582756_5fd523cb95f5f90dfa81845212241b6e_kx" target="_blank" rel="external nofollow" >

偷</a>

</div>

 二.實作

    上邊我們已經分析出這個網頁網遊就是一個WML的頁面,使用HTTP協定就可以進行通路。通過對WML頁面的解析我們就可以達到我們的目的。HTTP協定的資料交換我們可以使用.NET FRAMEWORK2.0開始提供的System.Net.WebClient這個類。該類已經提供了我們使用HTTP協定通路資料的大部分功能。

    首先我們來看看登入是如何使用WebClient登入。下邊的代碼顯示了我們如何通過WebClient發送表單進行網站登入的。一定要記得表單中所有的項目都要填寫全(參考登入的表單分析)。還有就是資料應該是用UTF-8進行編碼,如果不是的話資料一定會出錯的。

string postString = string.Format("email={0}&password={1}&remember=0&from=&login= 登 陸 ", userName, passWord);

webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

postData = Encoding.UTF8.GetBytes(postString);

responseData = webClient.UploadData("wap.kaixin001.com/home/", "POST", postData);

responseHtml = Encoding.UTF8.GetString(responseData);

    登陸後的頁面以字元串的形式儲存在了responseHtml這個變量中了。我們需要對這個頁面進行分析,還記得我們說要找到我們需要的連結麼?這裡我們通過正規表達式來獲所有的超連結,然後過濾出我們需要的連結。擷取超連結标簽我們不僅需要擷取其href屬性,我們還要擷取他的标簽的值。我們通過标簽的值來過濾我們需要的内容。擷取的超連結我們還需要進一步的處理。網頁中的超連結有些是絕對位址有些是相對位址,這裡我們需要進行轉換。還有就是我寫的正規表達式可能提取後的位址資訊中帶有雙引号,我們需要将雙引号剔除。在這就是網頁中定義了很多類似;&nbsp ;&amp這樣的轉義字元串,是以我們需要将相應的轉義字元串進行替換。這裡是個血的教訓,我就是沒有進行轉義字元的替換導緻直接被伺服器強制登出。

public class URLPart

{

public string url;

public string text;

public override string ToString()

{

return url + " " + "[" + text + "]";

}

}

public static URLPart[] HtmlGetUrl(string html)

{

URLPart[] parts;

List<URLPart> list = new List<URLPart>();

string regString = @"<a/b[^<>]*?/bhref[/s/t/r/n]*=[/s/t/r/n]*[""']?[/s/t/r/n]*(?<url>[^/s/t/r/n""'<>]*)[^<>]*?/?[/s/t/r/n]*>(?<value>.*?)</a>";

Regex reg = new Regex(regString);

MatchCollection matches = reg.Matches(html);

foreach (Match match in matches)

{

URLPart part = new URLPart();

part.url = match.Groups["url"].Value;

part.text = match.Groups["value"].Value;

list.Add(part);

}

parts = new URLPart[list.Count];

parts = list.ToArray();

return parts;

}

    我們通過下邊的方法找到并按照如下順序通路以下超連結[元件]->[買房子]->[花園菜地]->[可偷的菜地]。就可以到達好友的清單了。通過下邊的函數我們來過濾出我們的好友的連結。還記得上邊的好友清單的特征,因為好友清單中的連結不隻一頁是以還需要按照上邊分析出的特征找出所有的好友。但是為了效率和快速偷取的原則我們應該找到一頁的好友就偷一頁,然後再找再偷。

public static URLPart[] GetNames(string html)

{

URLPart[] parts = URLHelper.HtmlGetUrl(html);

List<URLPart> list = new List<URLPart>();

for (int i = 0; i < parts.Length; i++)

{

//首頁 |好友 |消息 |動态 |元件

if ((parts[i].text == "首頁") || (parts[i].text == "好友") || (parts[i].text == "消息") || (parts[i].text == "動态") || (parts[i].text == "元件"))

continue;

else if (parts[i].text == "下一頁" || parts[i].text == "上一頁")

{

break;

}

else

{

list.Add(parts[i]);

}

}

return list.ToArray();

}

    通過找到了好友的連結我們就通路進去就可以開始偷菜了。同樣的我們需要找到偷菜的連結。回想我們分析的偷菜頁面的連結。為了擷取更多的資訊我們應該不隻分析連結而是應該分析包含【偷】連結的整個<div>标簽,這樣我們才能知道在偷什麼。我們同樣使用正規表達式來擷取我們所需的資訊,不過這次我們用兩個這則表達式來擷取資料。這裡我們能夠擷取到偷的是什麼,偷的連結,以及标簽的既超連結所顯示的字。擷取連接配接時HtmlGetAppleUrl方法中的keyword起找到偷這個關鍵字的作用。例如 URLHelper.HtmlGetAppleUrl(responseHtml, "偷");

public class AppleURLPart : URLPart

{

public string appleName;

public override string ToString()

{

return appleName+" "+url + " " + "[" + text + "]";

}

}

public static AppleURLPart[] HtmlGetAppleUrl(string html,string keyword)

{

AppleURLPart[] parts;

List<AppleURLPart> list = new List<AppleURLPart>();

string regStringDiv = @"<div/b.*?>(?<apple>[/u4e00-/u9fa5]+).*?<br.*?/>.*?</div>";

string regStringUrl = @"<a/b[^<>]*?/bhref[/s/t/r/n]*=[/s/t/r/n]*[""']?[/s/t/r/n]*(?<url>[^/s/t/r/n""'<>]*)[^<>]*?/?[/s/t/r/n]*>(?<value>.*?)</a>";

Regex regDiv = new Regex(regStringDiv);

Regex regUrl = new Regex(regStringUrl);

MatchCollection matches = regDiv.Matches(html);

foreach (Match match in matches)

{

Match UrlMatch;

if (regUrl.IsMatch(match.Value))

{

UrlMatch = regUrl.Match(match.Value);

AppleURLPart applePart = new AppleURLPart();

applePart.appleName = match.Groups["apple"].Value;

applePart.text = UrlMatch.Groups["value"].Value;

applePart.url = UrlMatch.Groups["url"].Value;

if (applePart.text == keyword)

{

list.Add(applePart);

}

}

}

parts = list.ToArray();

return parts;

}

    找到【偷】的連結我們就可以大偷特偷了。下邊的代碼展示了如何進行執行偷這個動作。DoFilter()這個方法是我自己為了過濾掉不想偷的菜寫的過濾函數。比如像牧草,白菜這樣的不值錢的東西就不應該去偷,浪費有限的偷東西次數。HumanSim()方法用于模拟人的反映時間,因為人看網頁時有速度的,有時候反應快有時候反映慢我們應該模拟出這個過程進行随機的延時。不然有可能被伺服器封号。雖然随機延時很簡單,但是應該是個有效的方法。我們可以根據每次訪偷取連結後得到的結果頁面來分析是否偷取成功。這裡我直接查找字元串中是否包含成功這兩個子,如果包含的畫就算是偷取成功了。

protected void GetApple(AppleURLPart[] parts)

{

for (int i = 0; i < parts.Length; i++)

{

if (DoFilter(parts[i]))

{

HumanSim();

responseData = webClient.DownloadData(URLHelper.FullAddress(parts[i].url));

responseHtml = Encoding.UTF8.GetString(responseData);

int begin = responseHtml.IndexOf("成功");

int end;

if (begin == -1)

{

this.log.Text = "偷[[ " + parts[i].appleName + " ]]失敗 -_-|| 估計是給人偷幹淨了。。。。/r/n" + this.log.Text;

}

else

{

begin -= 2;

end = responseHtml.IndexOf("<", begin, 30);

string str = responseHtml.Substring(begin, end - begin);

this.log.Text = str + "/r/n" + this.log.Text;

}

}

else

{

this.log.Text = "破[[" + parts[i].appleName+ "]]我才懶得偷呢/r/n" + this.log.Text;

}

}

}

 三.寫在最後

     通過上邊的分析大家應該對這種網頁網遊的輔助工具編寫找到了一定的方法了。也許現在SNS網站上大部分遊戲都是FLASH界面的,但是沒有關系。雖然他的資料時FLASH界面但是我通過WinDump檢視其資料包的發送發現其大部分仍然使用了HTTP方式進行資料交換,隻不過連結被FLASH界面所掩蓋了,但原理仍然不變。是以仍然可以采取HTTP方式進行輔助程式的開發。