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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BUUCTF Dig the way

發布時間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BUUCTF Dig the way 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 題目類型
    • 查殼
    • 拖進ida
    • 整體邏輯
    • 文件讀取函數
      • fseek函數
      • ftell函數
      • fread函數(補充)
    • 分析三個func
      • func0
      • func1
      • func2
    • 解決方法分析
      • 分析

題目類型

這道題是一道棧溢出的題目,有點意思。

查殼


無殼

拖進ida

int __cdecl main(int argc, const char **argv, const char **envp) {int result; // eax@2int v4; // ebx@6size_t v5; // eax@8int v6; // ebx@11int v7; // [sp+1Ch] [bp-48h]@6int v8; // [sp+30h] [bp-34h]@1signed int v9; // [sp+34h] [bp-30h]@1signed int v10; // [sp+38h] [bp-2Ch]@1signed int v11; // [sp+3Ch] [bp-28h]@1int v12; // [sp+40h] [bp-24h]@1int v13; // [sp+44h] [bp-20h]@1int (__cdecl *v14)(int, int, int); // [sp+48h] [bp-1Ch]@1int (__cdecl *v15)(int, int, int); // [sp+4Ch] [bp-18h]@1int (__cdecl *v16)(int, int, int); // [sp+50h] [bp-14h]@1__int32 v17; // [sp+54h] [bp-10h]@3__int32 v18; // [sp+58h] [bp-Ch]@3FILE *v19; // [sp+5Ch] [bp-8h]@1__main();v14 = func0;v15 = func1;v16 = func2;v8 = 0;v9 = 1;v10 = 2;v11 = 3;v12 = 3;v13 = 4;v19 = fopen("data", "rb");if ( v19 ){fseek(v19, 0, 2);v18 = ftell(v19);fseek(v19, 0, 0);v17 = ftell(v19);if ( v17 ){puts("something wrong");result = 0;}else{for ( i = 0; i < v18; ++i ){v4 = i;*((_BYTE *)&v7 + v4) = fgetc(v19);}v5 = strlen((const char *)&v7);if ( v5 <= v18 ){v18 = v11;i = 0;v17 = v13;while ( i <= 2 ){v6 = i + 1;*(&v8 + v6) = (*(&v14 + i))(&v8, v12, v13);v12 = ++i;v13 = i + 1;}if ( v11 ){result = -1;}else{get_key(v18, v17);system("PAUSE");result = 0;}}else{result = -1;}}}else{result = -1;}return result; }

如何獲取到flag?
需要執行get_key函數,如果要執行,那么需要保證v11等于0。那么接下來我們來理理整體邏輯,

整體邏輯

v14 = func0;v15 = func1;v16 = func2;

v14,v15,v16三個函數指針,分別指向func0,func1,func2,讀取data文件到v7,v7數組只有20個字節的大小,如果文件內容超過20字節,那么就會依次向后(也就是說把v8,v9,v10等等)進行覆蓋

while ( i <= 2 ){v6 = i + 1;*(&v8 + v6) = (*(&v14 + i))((int)&v8, v12, v13);v12 = ++i;v13 = i + 1;}

v8的起始值是0,v6是1,所以這里func0(v14指向的函數)的返回值是賦給v9;func1(v15指向的函數)的的返回值是賦給v10;func2(v16指向的函數)的的返回值是賦給v11(這里是不是找到關鍵點了???func2的返回值給v11,繼續往下觀察)

文件讀取函數

fseek函數

FILE *fp = fopen(model_path, "rb"); fseek(fp, 0, SEEK_END)

用 法: int fseek(FILE *stream, long offset, int fromwhere);
描 述: 函數設置文件指針stream的位置。如果執行成功,stream將指向以fromwhere為基準,偏移offset個字節的位置。如果執行失敗(比如offset超過文件自身大小),則不改變stream指向的位置。
返回值: 成功,返回0,否則返回其他值。
參數:

  • stream:文件指針;
  • offset:偏移量,整數表示正向偏移,負數表示負向偏移;
  • fromwhere:設定從文件的哪里開始偏移,可能取值為:SEEK_CUR,SEEK_END 或 SEEK_SET
    SEEK_SET: 文件開頭
    SEEK_CUR: 當前位置
    SEEK_END: 文件結尾
  • 其中SEEK_SET,SEEK_CUR和SEEK_END和依次為0,1和2;
    例子:

  • fseek(fp,50L,0);把fp指針移動到離文件開頭50字節處;
  • fseek(fp,50L,1);把fp指針移動到離文件當前位置50字節處;
  • fseek(fp,50L,2);把fp指針退回到離文件結尾50字節處。
  • ftell函數

    FILE *fp = fopen(model_path, "rb"); fseek(fp, 0, SEEK_END); //fp指針移到文件尾部 int model_len = ftell(fp);

    用 法: long ftell(FILE *fp);
    描 述: 返回當前文件指針位置。這個位置是當前文件指針相對于文件開頭的位移量。
    返回值:返回文件指針的位置,若出錯則返回-1L。
    參數:文件指針。

    fread函數(補充)

    fread(buffer,100,1,fp)

    用 法: size_t fread( void *buffer, size_t size, size_t count, FILE *stream ) ;
    描 述: fread()用來從文件流中讀取數據。參數stream為已打開的文件指針,參數buffer指向欲存放讀取進來的數據空間,讀取的字節數以參數size * count來決定。
    返回值: 返回實際讀取到的count數目,如果此值比參數count來得小,則代表可能讀到了文件尾了或者有錯誤發生(前者幾率大),這時必須用feof()或ferror()來決定發生什么情況。
    參數:

  • buffer :讀取的數據存放的內存的指針(可以是數組,也可以是新開辟的空間,buffer就是一個索引);
  • size : 每次讀取的字節數 ;
  • count :讀取次數 ;
  • strean:要讀取的文件的指針;
  • 分析三個func

    func0

    signed int __cdecl func0(int a1, int a2, int a3) {int v3; // ST0C_4@1v3 = *(_DWORD *)(4 * a2 + a1);*(_DWORD *)(a1 + 4 * a2) = *(_DWORD *)(4 * a3 + a1);*(_DWORD *)(a1 + 4 * a3) = v3;return 1; }

    func0一看就是利用一個temp把兩個東西交換一下。

    func1

    int __cdecl func1(int a1, int a2, int a3) {int v3; // eax@1v3 = (*(_DWORD *)(4 * a2 + a1) + *(_DWORD *)(4 * a3 + a1)) >> 31;return (v3 ^ (*(_DWORD *)(4 * a2 + a1) + *(_DWORD *)(4 * a3 + a1)))- v3- (((*(_DWORD *)(4 * a3 + a1) >> 31) ^ *(_DWORD *)(4 * a3 + a1))- (*(_DWORD *)(4 * a3 + a1) >> 31))- abs(*(_DWORD *)(4 * a2 + a1))+ 2; }

    func1的return值化簡后為4a2+a1-abs(4a2+a1)+2(注意,這里我把右移31位直接看成0了,32位的數最高位為1被輸入的話很難遇到,直接忽略。)
    4a2+a1-abs(4a2+a1)+2也就是y=x-|x|+2的函數圖像,如下:

    這里返回值的分情況,有小于0,有大于0,有等于0

    func2

    int __cdecl func2(int a1, int a2, int a3) {int v3; // ecx@1v3 = (*(_DWORD *)(4 * a3 + a1) + *(_DWORD *)(4 * a2 + a1)) >> 31;return ((*(_DWORD *)(4 * a3 + a1) >> 31) ^ *(_DWORD *)(4 * a3 + a1))- (*(_DWORD *)(4 * a3 + a1) >> 31)- ((v3 ^ (*(_DWORD *)(4 * a3 + a1) + *(_DWORD *)(4 * a2 + a1)))- v3)+ abs(*(_DWORD *)(4 * a2 + a1))+ 2; }

    func2的return值化簡后為-4a2-a1+abs((4a2 + a1))+2(注意,這里我把右移31位直接看成0了,32位的數最高位為1被輸入的話很難遇到,直接忽略。)
    -4a2-a1+abs((4a2 + a1))+2也就是y=-x+|x|+2的函數圖像,如下:

    也就是說返回值恒大于0

    解決方法分析

  • 使func2返回值為0
  • 使v16函數指針指向的函數改變(指向v15)
  • 第一種方法,我們所畫出的函數恒為正,直接pass
    第二種方法,如何改變呢?這里func0本來就是用來交換的,直接在調用func0函數時傳func1函數的函數指針v15和func2函數的函數指針v16進行交換即可。交換之后,v16函數指針指向的函數就是func1,func1的返回值可正可負可為零,返回值賦給了v11,然后就可以對flag進行打印輸出。

    分析

    signed int __cdecl func0(int a1, int a2, int a3) {int v3; // ST0C_4v3 = *(_DWORD *)(4 * a2 + a1);*(_DWORD *)(a1 + 4 * a2) = *(_DWORD *)(4 * a3 + a1);*(_DWORD *)(a1 + 4 * a3) = v3;return 1; } *(&v8 + v6) = (*(&v14 + i))((int)&v8, v12, v13);

    觀察func0,此時func0函數中參與運算的起始地址是v8,偏移分別是v12(3)和v13(4),也就是說,此時func0交換的參數是v11和v12。要使參數變為v15和v16,就需要把偏移改為7和8,也就是把v12的值改為7,v13 的值改為8(其實顛倒過來也行)

    v7有20個字節,v8~v11是4個int,也就是4x4=16個字節,于是data文件需要從第36個字節開始,將v12和v13覆蓋為7和8。

    此時僅僅只是交換了兩個函數指針,如何保證func1的返回值為0呢?
    v15執行func2函數,v16執行func1函數,而在循環中v12和v13由i賦值,當執行v16(func1)函數時,v12和v13的值分別為2和3

    while ( i <= 2 ){v6 = i + 1;*(&v8 + v6) = (*(&v14 + i))((int)&v8, v12, v13);v12 = ++i;v13 = i + 1;}

    4a2+a1-abs(4a2+a1)+2,v10等于2,要使返回的值為0,則需v11為-1,于是同樣利用程序data讀文件的漏洞將v11覆蓋為-1

    flag: 8cda1bdb68a72a392a3968a71bdb8cda

    總結

    以上是生活随笔為你收集整理的BUUCTF Dig the way的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 中文字幕国产日韩 | 久久久国产精品一区二区三区 | 久草福利资源在线观看 | 日产毛片 | 久久精品第一页 | 在线中文字幕播放 | 精品人伦一区二区三区 | 肉丝肉足丝袜一区二区三区 | 天堂在线中文字幕 | 精品一区二区三区入口 | 特级一级黄色片 | 久久综合久久鬼色 | 国产精品人成在线观看免费 | 亚洲欧美另类国产 | 成人av一区二区在线观看 | 番号动态图 | 色偷偷噜噜噜亚洲男人的天堂 | 蜜桃成人在线观看 | 岛国色图 | 国产奶水涨喷在线播放 | 亚洲理论在线观看 | 香蕉久久夜色精品升级完成 | 狠狠夜 | 一区二区三区成人 | 不卡影院 | 91精品国产91久久久久久吃药 | 永久免费54看片 | 最好看的电影2019中文字幕 | 国产精成人品 | 国产亚洲精品久久久久婷婷瑜伽 | 欧美色图17p | 欧美日韩在线综合 | 国内视频精品 | 农村寡妇一区二区三区 | 日韩三级黄 | 女生喷液视频 | 日本日韩欧美 | 国产伦精品一区二区三区视频女 | 99re8在线精品视频免费播放 | 狠狠2020| 国产日韩91 | 国产熟妇与子伦hd | 雨宫琴音一区二区三区 | 中国亚洲老头同性gay男男… | 五月激情综合婷婷 | 日韩久久av | 女女同性女同一区二区三区按摩 | 调教在线观看 | 手机在线毛片 | 99视频在线免费 | 熟妇熟女乱妇乱女网站 | 乐播av一区二区三区 | 淫片一级国产 | 99热手机在线观看 | 亚洲毛片在线免费观看 | 三级视频在线播放 | 欧美囗交做爰视频 | 成人欧美在线观看 | 少妇久久精品 | 日韩精品免费一区二区 | 白浆在线| 91婷婷色| 日韩精品免费播放 | 久久国产视频网站 | 男女啪动最猛动态图 | 大尺度床戏视频 | 一区二区三区中文字幕 | 日韩电影在线观看一区 | 欧美成人午夜精品免费 | 久草成人在线 | 欧美乱妇日本无乱码特黄大片 | 夜夜嗨影院 | 9久9久9久女女女九九九一九 | 91高清在线免费观看 | 成人免费视频国产免费网站 | 久久婷婷五月国产色综合激情 | 老司机午夜影院 | 日本成人在线免费视频 | 精品一区二区三区在线播放 | 毛片视屏 | 欧美色图视频在线 | 免费手机av| 亚洲最新 | 日本黄色片视频 | 国产在线日韩 | 国产精品第一国产精品 | 久草大 | 日韩中文字幕第一页 | 福利视频免费观看 | 亚洲美女性生活视频 | 这里精品 | 精品视频一区二区三区四区 | av在线收看| 久久久一级 | 久久一线| 国产午夜伦理 | 操大逼网站 | 欧美日韩黄色网 | 91看毛片 |