日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

IDC:函数

發(fā)布時(shí)間:2024/3/12 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IDC:函数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

IDC:函數(shù)

  • IDC腳本中的函數(shù)必須要有返回值。在IDC腳本中,支持兩類函數(shù):

  • 內(nèi)建函數(shù)

  • 用戶自定義函數(shù)

  • 用戶自定義函數(shù)一般是像下面這樣的方式寫的:

    static func(arg1,arg2,arg3) {statements ... }

    需要注意的一點(diǎn)是,聲明函數(shù)參數(shù)的時(shí)候,沒必要指定函數(shù)參數(shù)的類型了,因?yàn)镮DC會(huì)根據(jù)你傳入的參數(shù)自動(dòng)進(jìn)行參數(shù)類型轉(zhuǎn)換的。

  • 默認(rèn)情況下,函數(shù)調(diào)用的時(shí)候參數(shù)傳遞是按值傳遞的,但是以下三種情況例外(引用傳遞):

  • 對(duì)象類型的參數(shù)總是使用引用方式傳參

  • 函數(shù)類型的參數(shù)總是使用應(yīng)用方式傳參

  • 還可以強(qiáng)制使用 & 符號(hào)來讓參數(shù)使用引用方式傳參

  • 如果IDC腳本中調(diào)用的函數(shù)不存在,IDA就會(huì)嘗試解析并使用當(dāng)前被調(diào)試的進(jìn)程中的符號(hào)或者標(biāo)簽,如果解析成功,那么就會(huì)執(zhí)行一次 AppCall(AppCall稍后會(huì)進(jìn)一步解釋)

IDC:AppCall

  • 首先需要明確一點(diǎn),AppCall是IDC腳本中的一個(gè)內(nèi)建函數(shù)

  • 先來看函數(shù)原型

    anyvalue Appcall(ea, type, ...);
    • 功能:調(diào)用被調(diào)試進(jìn)程的函數(shù)

    • 參數(shù):ea - 調(diào)用的函數(shù)地址

    • 參數(shù):type - 調(diào)用的函數(shù)的類型或者說方式,支持三種調(diào)用形式

    • 字符串形式,比如:“int func(void);”

    • 類型對(duì)象形式,比如:GetTinfo(ea)

    • 零:相當(dāng)于讓IDA自行決定,這種情況下,類型一般是從idb中進(jìn)行獲取的

    • 參數(shù):..., 這個(gè)是可變參數(shù),用來傳遞你要調(diào)用的函數(shù)的參數(shù)

    • 返回值:被調(diào)用函數(shù)的返回值

    • Remark:如果函數(shù)調(diào)用失敗,并且失敗的原因是內(nèi)存訪問異常或者其他異常,腳本會(huì)拋出一個(gè)runtime錯(cuò)誤信息,可以在腳本中使用 try/catch 進(jìn)行異常捕獲。在實(shí)際的使用過程中,很少使用AppCall這個(gè)函數(shù)調(diào)用,只是說IDA擁有這種在IDC腳本中存在未知函數(shù)的時(shí)候嘗試在被調(diào)試進(jìn)程中匹配符號(hào)的能力,舉個(gè)例子:_printf("hello\n") 這條語句會(huì)調(diào)用被分析程序的 _printf 函數(shù)

  • AppCall函數(shù)有2個(gè)選項(xiàng)可以使用,我們可以在IDC腳本中使用 SetAppcallOptions宏進(jìn)行設(shè)置:

  • #define APPCALL_MANUAL 0x0001

    • 只設(shè)置AppCall, 不執(zhí)行,執(zhí)行完畢之后,需要調(diào)用一次 CleanupAppcall

  • #define APPCALL_DEBEV 0x0002

    • 返回調(diào)試詳細(xì)信息, 如果設(shè)置了這個(gè)標(biāo)志位,當(dāng)AppCall執(zhí)行過程中發(fā)生異常的時(shí)候,會(huì)生成一個(gè)包含詳細(xì)異常信息的異常對(duì)象

  • #define APPCALL_TIMEOUT 0x0004

    • AppCall調(diào)用的超時(shí)時(shí)間, 超時(shí)時(shí)間是以毫秒為單位的,并且值是放在option的高2位字節(jié)中,如果AppCall調(diào)用超時(shí),錯(cuò)誤信息會(huì)放到 errbuf中,并且值是字符串 timeout

  • #define SET_APPCALL_TIMEOUT(x) ((x<<16)|0x0004)

    • 指定AppCall超時(shí)時(shí)間的時(shí)候,需要拼裝option的值,這個(gè)就是一個(gè)輔助宏,用來生成option的值

  • 使用AppCall這個(gè)功能,可以很隨意的調(diào)用被調(diào)試進(jìn)程內(nèi)的函數(shù)而不需要進(jìn)行任何的dll注入或者修改被調(diào)試進(jìn)程的內(nèi)存,如果被調(diào)用的函數(shù)名稱存在的話,AppCall還可以簡(jiǎn)化成 func(args)的形式,前提是func這個(gè)符號(hào)是存在的,舉個(gè)例子:

    verinfo = object(); verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); GetVersionExA(&verinfo);

    上面這段代碼將會(huì)在被調(diào)試進(jìn)程內(nèi)創(chuàng)建一個(gè)OSVERSIONINFOA結(jié)構(gòu)體,并且將結(jié)構(gòu)體地址傳遞給GetVersionExA調(diào)用,調(diào)用完畢之后,verinfo 對(duì)象就被轉(zhuǎn)換成了IDC對(duì)象,內(nèi)存結(jié)構(gòu)如下:

    object__at__: 18FEB0hdwBuildNumber: 7600.dwMajorVersion: 6.dwMinorVersion: 1.dwOSVersionInfoSize:dwPlatformId: 2.szCSDVersion: "\x00\x00\x00\x00..."

    其中_at_屬性表示這個(gè)結(jié)構(gòu)體的內(nèi)存地址,在這個(gè)例子中verinfo是一個(gè)臨時(shí)變量,所以_at_的值意義不大,大家在使用使用的過程中可能會(huì)遇到這個(gè)值很有用的情況。

  • AppCall會(huì)自動(dòng)在IDC對(duì)象和C對(duì)象之間進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換的時(shí)候依據(jù)IDA中擁有的類型信息來進(jìn)行,但是還要遵循以下幾個(gè)轉(zhuǎn)換規(guī)則:

  • 基本數(shù)據(jù)類型:

    • 如果目標(biāo)數(shù)據(jù)類型也是一個(gè)基本數(shù)據(jù)類型(非指針),只需要執(zhí)行簡(jiǎn)單的轉(zhuǎn)換即可(附帶符號(hào)處理或者截?cái)嗵幚?#xff09;,比如: IDC中的值-1轉(zhuǎn)換成 _int32(0xFFFFFFFF),IDC中的0x555轉(zhuǎn)換成 _int8(0x55)

  • 指針:

    • 如果目標(biāo)類型是一個(gè)指針,并且IDC的值是一個(gè)字符串,這個(gè)字符串就轉(zhuǎn)換成一個(gè)指針對(duì)象,字符串的內(nèi)容直接拷貝到被調(diào)試進(jìn)程,后面追加一個(gè)結(jié)束符 \0

    • 如果對(duì)應(yīng)的IDC的值是一個(gè)數(shù)字,轉(zhuǎn)換之后的結(jié)果是指針?biāo)赶虻膬?nèi)存的值是這個(gè)數(shù)值,如果你想得到一個(gè)數(shù)值的地址,可以直接使用 &符號(hào)

    • 如果對(duì)應(yīng)的IDC值不是字符串,那這個(gè)值將會(huì)轉(zhuǎn)換成一個(gè)對(duì)象,指針指向的內(nèi)存使用這個(gè)對(duì)象進(jìn)行初始化

  • 結(jié)構(gòu)體

    • 如果目標(biāo)類型是一個(gè)結(jié)構(gòu)體,IDA會(huì)通過對(duì)應(yīng)的屬性來嘗試一個(gè)一個(gè)的初始化結(jié)構(gòu)體的成員。比如:在上面的例子中只有dwOSVersionInfoSize 屬性存在,那么這個(gè)結(jié)構(gòu)體字段就使用這個(gè)屬性類初始化,對(duì)于不存在的字段直接初始化成0

  • 數(shù)組

    • 數(shù)組的每個(gè)元素都是單獨(dú)初始化的,當(dāng)然如果對(duì)應(yīng)的IDC值是字符串除外,因?yàn)樽址旧砭褪强梢援?dāng)成一個(gè)完整的數(shù)組來使用的。

  • 下面針對(duì)上述的幾種情況,我們來舉一些例子:

  • 調(diào)用printf

    auto n = 5;auto s = "short";_printf("Hello world, number is %d, string is %s\n", n, s);
  • 調(diào)用sscanf

    auto x; auto nsuccess = _sscanf(s, "%d", &x);
  • 結(jié)構(gòu)體使用

    verinfo = object();GetVersionExA(verinfo);
  • 另外,_userCall 這個(gè)內(nèi)建調(diào)用也是支持這些自動(dòng)轉(zhuǎn)換的

  • 對(duì)于會(huì)發(fā)生異常的調(diào)用,配合APPCALL_MANUAL 標(biāo)志位,可以實(shí)現(xiàn)單步的效果,具體方式還需要大家仔細(xì)去研究一下.

總結(jié)

以上是生活随笔為你收集整理的IDC:函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。