最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

【滴水基礎(chǔ)】4.Win32Api調(diào)用(下1)

2023-02-24 22:41 作者:沙漠里的鯨  | 我要投稿

第二十二:文件系統(tǒng)

#文件系統(tǒng)定義:

---OS用于管理磁盤上文件的方法和數(shù)據(jù)結(jié)構(gòu),即在磁盤上如何組織文件的方法(不同OS的方法不同,windows 硬盤文件格式是fat32NTSF,而linux 需要的文件格式是ext2或ext)

---Windows的磁盤文件格式:

---現(xiàn)在一般都是NTFS:

---優(yōu)點是:安全性和穩(wěn)定性,使用中不易產(chǎn)生文件碎片。

---并且能對用戶的操作進(jìn)行記錄,通過對用戶權(quán)限進(jìn)行嚴(yán)格的限制,使每個用戶只能按照系統(tǒng)賦予的權(quán)限進(jìn)行操作,充分保護(hù)了系統(tǒng)與數(shù)據(jù)的安全。

---其中,EFS可以對文件進(jìn)行加密(我這里是灰色,要啟動)

---CMD窗口,輸入services.msc打開計算機(jī)服務(wù),然后啟動EFS就可以進(jìn)行文件加密

---被加密的文件,只有當(dāng)前用戶可以使用,其它用戶不能查看

---磁盤配額:計算機(jī)中指定磁盤的儲存限制,就是管理員可以為用戶所能使用的磁盤空間進(jìn)行配額限制,每一用戶只能使用最大配額范圍內(nèi)的磁盤空間。

---限制指定賬戶能夠使用的磁盤空間,這樣可以避免因某個用戶的過度使用磁盤空間造成其他用戶無法正常工作甚至影響系統(tǒng)運(yùn)行。

----在服務(wù)器管理中此功能非常重要,但對單機(jī)用戶來說意義不大。

#卷

---文件系統(tǒng)的最上層,如C盤、D盤、E盤(下一級為文件目錄)

#卷相關(guān)API

---獲取卷

---輸出十六進(jìn)制1c,對于的二進(jìn)制:0001 1100

---從數(shù)據(jù)低位高位,分別對應(yīng)ABCDEF,那么我這里是存在C盤、D盤和E盤

---獲取一個卷的盤符字符串

---相關(guān)代碼

---這里有點問題,只能打印開頭

---直接下斷點查看szBuff的內(nèi)存

---發(fā)現(xiàn)輸出了C:\ 和D:\和E:\

---獲取卷的類型

---注意:一定要加 //,我剛開始用 D:\ 就報錯了

---查看35對應(yīng)的卷的類型:可移動磁盤和網(wǎng)絡(luò)磁盤(驅(qū)動器不能識別,返回0)

---獲取卷的詳細(xì)信息

---lpVolumeNameBuffer:卷標(biāo)名稱(相當(dāng)與給當(dāng)前磁盤取得別名,這里為Data)

---獲取卷的指定信息

---打印的信息如下:

#目錄相關(guān)API

---創(chuàng)建文件CreateDirectory()

---如果在創(chuàng)建時不指定絕對路徑,就會創(chuàng)建在:當(dāng)前進(jìn)程的工作目錄

---在C盤下面創(chuàng)建A目錄,并且更名為B目錄,最后刪除目錄

---獲取當(dāng)前進(jìn)程的目錄并且修改

---輸出如下:

#文件相關(guān)的API

---獲取文件的大小

---獲取文件的屬性

---接受文件屬性的結(jié)構(gòu)體

---創(chuàng)建文件并獲取文件的

---結(jié)果如下:這里獲取文件大小失敗

---我按照這個方法嘗試了還是不行:https://bbs.csdn.net/topics/380103266?page=2

---注意:這里的時間是FILETIME結(jié)構(gòu)體

---需要使用

---這里網(wǎng)上找了個粒子

---效果如下(不知道正確與否):

#讀取文件

---設(shè)置讀取的位置

---讀取文件

----創(chuàng)建文件寫入內(nèi)容

---讀取

---輸出如下

---寫入文件

---拷貝文件

---在D盤根目錄新建HuangBo.txt,輸入123456789

---1.寫入“中國“4Byte(默認(rèn)是ASCII),但是沒有使用FlushViewOfFile更新緩存,所有這里獲取任然是之前的文件大?。?Byte

---2.這里WriteFile存在一個弊端,就是寫在文本的首部而不是尾部,并且把原來的1234這4個字節(jié)覆蓋掉了

---這里發(fā)現(xiàn)HuangBo.txt被刪除,而且復(fù)制也成功了

#內(nèi)存映射之文件共享

---A進(jìn)程修改文件的值,本質(zhì)是修改物理內(nèi)存的值

---B進(jìn)程讀取文件的值,本質(zhì)是讀取物理內(nèi)存的值

---創(chuàng)建文件HuangBo.txt,寫入:中國China!;然后讀取

---效果如下

---當(dāng)然,也可以通過創(chuàng)建物理頁、虛擬內(nèi)存和文件相互關(guān)聯(lián)的方式,然后直接讀取程序的內(nèi)存

---查找文件(遍歷某個盤的重要文件)

第二十三:內(nèi)存映射文件

---用ULtraEdit打開Dbgview.exe

---由于計算機(jī)是小端存儲,數(shù)據(jù)低位對應(yīng)內(nèi)存低位,數(shù)據(jù)高位對應(yīng)內(nèi)存高位

---那么一個指向Dbgview.exe首地址的DWORD指針,讀取的應(yīng)該是 00 90 5A 4D

---讀取Dbgview.exe首地址的4Byte(這里用內(nèi)存讀取的弊端:只能讀取4Byte,不能像讀取文本一樣讀取數(shù)組的形式)

---讀取效果如下

---如果想在0000 004c的位置寫入1DWORD的數(shù)據(jù),就要在指針處

---一般修改不是實時修改,而是關(guān)閉進(jìn)程后修改

---所有需要FlushViewOfFile函數(shù)更新緩存

---讀取并且修改0000 004c處的值

---我這里不要刷新也可以修改

---對應(yīng)B進(jìn)程,也可以通過打開物理內(nèi)存來讀取A進(jìn)程寫入物理內(nèi)存的值

---B進(jìn)程讀取物理內(nèi)存(重開一個VC界面)

---2個進(jìn)程同時運(yùn)行,發(fā)現(xiàn)讀取成功

---需要注意:2個進(jìn)程對應(yīng)的虛擬內(nèi)存可能是不一樣的,但是偏移是一樣的

#內(nèi)存映射之寫拷貝

---1個進(jìn)程可以看成1個exe模塊和多個dll組成(系統(tǒng)dll+自己的dll)

---這些DLL在物理頁上只有1塊,進(jìn)程使用dll的本質(zhì):映射物理頁

---那么,當(dāng)一個進(jìn)程在使用kenel32.dll,另一個進(jìn)程也在進(jìn)行寫操作怎么辦?

---在kernal32.dll中的某個函數(shù)下個斷點

---斷點的本質(zhì):把程序的匯編改為int 3,對應(yīng)的機(jī)器碼:0xCC

---或者在OD的某個函數(shù)頭按F2(本質(zhì)是將函數(shù)的機(jī)器碼第一個Byte改為:0xCC)

---那么,B進(jìn)程執(zhí)行kernel32.dll其中的函數(shù)時,遇到該斷點也會停止(但是實際上,B進(jìn)程根本不受到斷點的影響

---寫拷貝FILE_MAP_COPY(MapViewOfFile:物理頁和虛擬內(nèi)存映射):

---系統(tǒng)會從系統(tǒng)頁交換文件調(diào)撥物理存儲器,大小有dwNumberOfBytesToMap指定。

---只要我們不執(zhí)行讀取數(shù)據(jù)之外的任何操作,系統(tǒng)就不會使用從頁交換文件中調(diào)撥頁面?。

---但是一旦有任何線程寫入文件映射視圖的任何地址,系統(tǒng)就會從已經(jīng)調(diào)撥的頁交換文件中選擇一個頁面把原始數(shù)據(jù)復(fù)制到頁交換文件中的頁面,然后讓線程進(jìn)行修改這個副本,再將此頁面映射到進(jìn)程地址空間中。因此任何線程都只會修改數(shù)據(jù)的副本而不會修改原始數(shù)據(jù)。

---也就是說:當(dāng)一個進(jìn)程執(zhí)行寫操作的時候,就會復(fù)制一個新的物理頁

---例如:將AB進(jìn)程的虛擬內(nèi)存和物理頁映射的權(quán)限均改為:FILE_MAP_COPY(MapViewOfFile)

---發(fā)現(xiàn)A進(jìn)程雖然修改了,但是B進(jìn)程讀取的任然是原來未修改的值

#總結(jié)寫拷貝:

---不影響文件的執(zhí)行

---避免別的進(jìn)程受到影響

第二十四:靜態(tài)鏈接庫

---軟件模塊化的一種思路:

#創(chuàng)建靜態(tài)鏈接庫

---選擇預(yù)編譯頭文件

---在ClassViewz中new Class,發(fā)現(xiàn)分別生成A.cpp和A.h

---在A.h中聲明函數(shù)

---在A.cpp中實現(xiàn)函數(shù),并且構(gòu)建Build(F7)

---在A/Debug目錄下生成了A.lib

---將A.lib和A.h復(fù)制到桌面(這兩個就是編譯后的靜態(tài)鏈接庫程序)

---然后新建控制臺項目Test.cpp,如果Test項目想使用靜態(tài)鏈接庫,有2種方法

---第一:直接將A.lib和A.h復(fù)制到Test項目的目錄下

---在FileView處,插入文件到項目

---然后在Main程序里面調(diào)用靜態(tài)鏈接庫,發(fā)現(xiàn)構(gòu)建(build)成功

---VC6里面的Compile(Ctrl+F7)和Build(F7)的區(qū)別

---“compile"是“編譯”,對你的代碼進(jìn)行語法檢查,將你的文本程序語言轉(zhuǎn)化成計算機(jī)可以運(yùn)行的“01010…”形式的二進(jìn)制文件。compile過程生成“.obj”文件或”.o"文件,這個和編譯器有關(guān),vc++中是“.obj”文件。

---“build”是“鏈接”:將你在程序中調(diào)用到的類庫融合到你的程序中,比如你用到了printf()函數(shù),那么內(nèi)部實現(xiàn)該函數(shù)的類庫代碼就會添加到你的程序中。build過程生成“.exe”文件。這個可以直接運(yùn)行(注意:是直接放到exe內(nèi)存中)
---理論上來說應(yīng)該先點"complile",再點"build"。不過在vc++中直接點“build”它會自動先給你compile再build

---第二種:將靜態(tài)鏈接庫放到VC6的自帶系統(tǒng)庫里面

---將A.h放入Include目錄下,將A.lib放入Lib目錄下

---在工程>設(shè)置>鏈接>對象/模塊庫中添加A.lib

---然后使用包含系統(tǒng)頭文件的方式包含<A.h>

---發(fā)現(xiàn)執(zhí)行成功

---查看反匯編:發(fā)現(xiàn)難以區(qū)分自己寫的和靜態(tài)鏈接庫

---可以看出和自己寫的差不多,但是有時候程序會反復(fù)的調(diào)用靜態(tài)鏈接庫,那么,相當(dāng)于重復(fù)的寫了多分相同的代碼,然后Compile到了exe中,最后造成浪費(fèi)

#總結(jié)

第二十五:動態(tài)鏈接庫

#什么是動態(tài)鏈接庫(Dynamic Link Libary簡稱DLL)

---Dll是微軟在OS中,實現(xiàn)共享函數(shù)庫概念的一種方式,這些庫函數(shù)的擴(kuò)展名(“dll”、".ocx")

---發(fā)現(xiàn)1個進(jìn)程里面存在一個exe和多個Dll(DLL不會使得exe模塊的體積變大)

---雖然有許多進(jìn)程共用DLL(如kernel32.dll),但是DLL模塊在物理頁上只存在1份(寫拷貝權(quán)限),解決了靜態(tài)鏈接庫exe模塊包含相同代碼的問題。(只有寫操作才會復(fù)制到物理頁)

#創(chuàng)建動態(tài)鏈接庫

---發(fā)現(xiàn)創(chuàng)建了一個主函數(shù),以及一個頭文件,和頭文件的實現(xiàn)cpp

---在B.cpp發(fā)現(xiàn)主函數(shù)和Main()有所不同

---新建類MyDll.cpp和MyDll.h

---在MyDll.h中聲明加法Plus和減法Sub

---在MyDll.cpp實現(xiàn)2個函數(shù)

---但是這樣自己進(jìn)程可以使用,別人進(jìn)程不能使用

---需要按照特定的格式進(jìn)行聲明

#什么是調(diào)用約定

----常見的調(diào)用約定有:__cdecl(C語言默認(rèn))、__fastcall、__stdcall、__thiscall

---在MyDll.h中按照動態(tài)鏈接庫的格式進(jìn)程聲明

---extern:全局函數(shù);“C”:按照C語言的語法導(dǎo)出函數(shù),_declspec(dllexport):動態(tài)鏈接庫的導(dǎo)出聲明

---在MyDll.cpp中注意到聲明調(diào)用約定

#總結(jié)

---Dll、exe都是一個模塊,而有些模塊在執(zhí)行時需要使用其它模塊的功能

---dll的作用:為其它模塊提供功能(函數(shù))

---在PE(文件在OS中必須遵循的一種文件結(jié)構(gòu))中,dll存在導(dǎo)出表(說明提供了那些函數(shù)),而exe未必存在導(dǎo)出表

#PELoad查看導(dǎo)出表

---PELoad下載:https://down.52pojie.cn/Tools/PEtools/LordPE.7z

---使用PELoad打開B.dll>目錄>輸出表>...

---可以從導(dǎo)出表中發(fā)現(xiàn),B.dll提供了2個函數(shù),函數(shù)名為Plus和Sub,而且參數(shù)的大小都為8Byte,Offset為偏移

---而打開一個exe的helloword文件,發(fā)現(xiàn)沒有導(dǎo)出表

---除了使用頭文件進(jìn)行extern "C" _declspec(dllexport)方式生成導(dǎo)出表

---也可以使用 .def 文件生成導(dǎo)出表

---將MyDll.h和MyDll.cpp重置為正常

---添加文本文件,后綴名為.def

---在B.def寫下要導(dǎo)出的函數(shù),以及顯不顯示函數(shù)名

---編譯后,用LoadPE打開導(dǎo)出表,發(fā)現(xiàn)指定的函數(shù)名被隱藏,而且可以指定序號,也沒有參數(shù)大小(更加方便便捷)

---VC6新建一個控制臺項目,然后將之前的B.dll放入目錄下

#在2_19.cpp中使用B.dll(顯式鏈接)

---獲取函數(shù)在虛擬內(nèi)存的地址GetProcAddress(主要爭對dll)

---具體的代碼如下

---執(zhí)行結(jié)果如下:

---動態(tài)鏈接庫優(yōu)點(顯示鏈接):不把dll加入exe模塊中,現(xiàn)用現(xiàn)找,非常方便,減少重復(fù)代碼;缺點:加載不方便

第二十六:隱式鏈接

#顯式鏈接:

---優(yōu)點:靈活,什么時候想調(diào)用就調(diào)用;缺點:相對繁瑣,需要獲取函數(shù)地址

#隱式鏈接

---在上一節(jié)的B.dll中,將導(dǎo)出表修改如下,其它地方不變

----發(fā)現(xiàn)在Debug目錄下生成了B.dll(顯式鏈接只使用了B.dll)和B.lib

---靜態(tài)鏈接庫里面的lib文件包含了真正的代碼,而動態(tài)鏈接庫的lib文件不包含真正的代碼,只是一些輔助性的信息

#隱式鏈接的使用

---在之前使用dll時我們根本沒使用.lib文件,因為函數(shù)根本不在他里面。他不是靜態(tài)鏈接庫里的lib文件。

---但是這里面有著輔助信息,所以我們要使用隱式鏈接的話就要使用他,來讓編譯器找到dll。

---將B.dll和B.lib放到工程目錄下

---然后在main函數(shù)里面調(diào)用動態(tài)鏈接庫

---我們使用有著輔助信息的B.lib,所以我們要使用隱式鏈接的話就要使用他來讓編譯器找到B.dll。

---執(zhí)行如下

---注意:如果是以extern "C"導(dǎo)出的dll和lib

---那么,在加入函數(shù)說明的時候,也有加上extern "C"

#總結(jié)

---查看隱式鏈接的反匯編

---發(fā)現(xiàn)call的是一個進(jìn)程內(nèi)存的值(也就是說:將Sub函數(shù)的地址,存儲進(jìn)了緩沖區(qū)中)

#總結(jié)

---靜態(tài)庫(將靜態(tài)庫編譯到exe中,所以call的是一個程序的函數(shù)地址)

---動態(tài)庫(間接調(diào)用,將dll和exe分開編譯,留出一個緩沖區(qū),真正運(yùn)行的時候,才會把dll函數(shù)在進(jìn)程空間的地址傳給緩沖區(qū))

---在B.dll里面(隱式鏈接),會生成一個導(dǎo)出表

---當(dāng)然:B.dll也可能會存在導(dǎo)入表,因為dll也可能調(diào)用其它的dll

---而在隱式鏈接的exe中,也會存在一個導(dǎo)入表(一定存在),但是通常沒有導(dǎo)出表

#隱式鏈接的調(diào)用流程

---1.exe啟動時,將調(diào)用的函數(shù)地址的緩沖區(qū)空出

---2.OS根據(jù)B.lib的輔助信息找到B.dll,然后調(diào)用LoadLibarary()加載dll到虛擬內(nèi)存

---3.OS調(diào)用GetProcAddress()獲取dll中函數(shù)的虛擬地址

---4.將函數(shù)的地址,放入緩沖區(qū),然后call dword ptr[緩沖區(qū)地址]

---因此:隱式鏈接和顯式鏈接沒有太大的區(qū)別,一個是自己寫代碼調(diào)用,一個是OS寫代碼自動調(diào)用

#DllMain函數(shù)

---和main()函數(shù)一樣,Dll也存在主函數(shù),但是DllMain()函數(shù)可以執(zhí)行多次

---對應(yīng)dll調(diào)用的原因,可能存在以下幾點

---在B的DllMain()函數(shù),重新生成B.dll

---然后使用顯式鏈接,調(diào)用B.dll

---分別在LoadLibrary()和FreeLibrary()下斷點調(diào)試,發(fā)現(xiàn)DllMain()函數(shù)被調(diào)用2次

---將B的DllMain()修改為

---然后main()函數(shù)創(chuàng)建線程

---發(fā)現(xiàn)線程調(diào)用也會觸發(fā)DllMain()函數(shù)

第二十七:遠(yuǎn)程線程

#線程

---線程是附屬在進(jìn)程上的執(zhí)行實體,是代碼的執(zhí)行流程

---代碼必須要通過線程才能執(zhí)行

#創(chuàng)建遠(yuǎn)程線程CreateRemoteThread()

---創(chuàng)建一個Test.exe進(jìn)程,創(chuàng)建1個線程,調(diào)用1個打印函數(shù)

---打印了0-9

---創(chuàng)建一個遠(yuǎn)程線程.cpp,通過CreateRemoteThread()為Test.exe進(jìn)程創(chuàng)建遠(yuǎn)程線程

---首先,需要通過OpenProcess獲取Test.exe的進(jìn)程句柄(根據(jù)進(jìn)程ID獲取句柄)

---在遠(yuǎn)程線程.cpp中,創(chuàng)建遠(yuǎn)程注入函數(shù)

---通過任務(wù)管理器查看Test.exe的進(jìn)程PID:8332

---通過反匯編查看進(jìn)程的線程函數(shù)地址:0x0040D460

---在主函數(shù)里面調(diào)用遠(yuǎn)程線程函數(shù)注意進(jìn)程

---發(fā)現(xiàn)Test.exe中的線程又執(zhí)行了一次

第二十八:遠(yuǎn)程線程注入

---如果想要讓遠(yuǎn)程線程執(zhí)行自己自定義的函數(shù)

---將預(yù)定的程序注入DLL,讓注入的進(jìn)程執(zhí)行DLL

#什么是注入

---在第三方進(jìn)程不知道/不允許的情況下,將模塊/代碼寫入對方的進(jìn)程空間,并且設(shè)法執(zhí)行的技術(shù),在安全領(lǐng)域,注入與反注入的對抗愈發(fā)激烈。

#遠(yuǎn)程注入流程

---由于LoadLibrary()和ThreadProc()的格式,傳參返回值都是4Byte

---而基本上exe執(zhí)行都會調(diào)用kernel32.dll,所以只要是exe都會調(diào)用LoadLibrary()函數(shù),而普通的exe,不一定會創(chuàng)建線程調(diào)用ThreadProc()函數(shù)

---思路:在進(jìn)程A中創(chuàng)建線程,將線程函數(shù)指定為LoadLibrary(),通常我們把要實現(xiàn)的功能封裝到一個dll里,然后想辦法讓A進(jìn)程加載這個dll(前提是同一臺電腦

%5Cbullet%201.在進(jìn)程A中分配空間,存儲“A.dll”

%5Cbullet%202.獲取LoadLibrary()的地址

%5Cbullet%203.創(chuàng)建遠(yuǎn)程線程,執(zhí)行LoadLibrary()函數(shù)(傳參)

---使用WriteProcessMemory拷貝A.dll的路徑到目標(biāo)進(jìn)程虛擬空間,進(jìn)行傳參

#創(chuàng)建動態(tài)鏈接庫A.dll

---MyDll.h

---MyDll.cpp

---MyDll.def

---A.cpp

---通過DtDebug獲取test.exe中LoadLibrary()加載kernel32.dll時的地址

---打開test.exe > 點E > 點擊kernel32.dll > 按Ctrl+N > 找到LoadLibraryA的程序地址:766c27F0

---注意:不同進(jìn)程的LoadLibraryA是一樣的

---將A.dll放到遠(yuǎn)程線程的工作空間里面,然后在遠(yuǎn)程線程.cpp

---遠(yuǎn)程線程.h

---Main.cpp

---先執(zhí)行Test.exe,然后再執(zhí)行main.cpp

---在DtDebug中,文件>attach > Test.exe > 按E,查看進(jìn)程加載的模塊

---發(fā)現(xiàn):A.dll已經(jīng)加載到了Test.exe的內(nèi)存空間中,但是沒有執(zhí)行dll

---利用Dll的入口函數(shù)DllMain()來執(zhí)行自定義的程序

---在A.dll的A.cpp修改如下

---重新生成A.dll,注入到Test.exe中

---發(fā)現(xiàn)不僅加載了dll,還執(zhí)行了A.dll中的惡意代碼

第二十九:進(jìn)程間通信

---1.不同主機(jī):Socket;2.同一臺主機(jī):物理頁

#創(chuàng)建一個Game.cpp,根據(jù)鍵盤輸入執(zhí)行操作

---利用DtDebug查看Game.exe三個函數(shù)的位置(結(jié)合堆棧圖觀察call的位置

---也可以使用VC6的反匯編查看

---三個函數(shù)的地址:00401030(Attack)、00401080(Reset)、004010D0(Blood)

#創(chuàng)建一個Dll(WGDLL.cpp)

#創(chuàng)建一個給Game.exe加載WGDLL.dll的控制臺.cpp

---StdAfx.h

---StdAfx.cpp

---控制臺.cpp

---效果如下:

#總結(jié):

---在控制臺和Dll進(jìn)程之間,創(chuàng)建一個共享內(nèi)存(4KB)

---讓Game.exe加載Dll,并執(zhí)行DllMain()和線程里面的控制命令

---控制臺每隔1S將命令寫入共享內(nèi)存(4Byte)

---DLL線程不間斷的獲取共享內(nèi)存(每個循環(huán)獲取到特定命令,取出后,將共享內(nèi)存設(shè)置為NULL,等待下一次循環(huán))

---控制臺每隔又將命令寫入共享內(nèi)存(比獲取的慢),DLL線程獲取,直到DLL線程獲取到結(jié)束釋放DLL的命令。

【滴水基礎(chǔ)】4.Win32Api調(diào)用(下1)的評論 (共 條)

分享到微博請遵守國家法律
马关县| 昂仁县| 韶山市| 荣昌县| 阿拉尔市| 昔阳县| 泽普县| 观塘区| 山西省| 屏东县| 灵山县| 元阳县| 雷州市| 平阳县| 上思县| 福泉市| 凉城县| 邵东县| 东莞市| 东乡族自治县| 遂溪县| 城市| 寿阳县| 灵武市| 犍为县| 峨山| 通城县| 南溪县| 七台河市| 宣武区| 南川市| 老河口市| 临城县| 阿尔山市| 北宁市| 阜新| 浮梁县| 观塘区| 濮阳县| 讷河市| 商南县|