最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++逆向分析移除鏈表元素實(shí)現(xiàn)方法詳解

 更新時(shí)間:2022年11月29日 11:15:42   作者:ch132  
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(203.移除鏈表元素),本篇文章通過逆向分析的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下

前言

這次的題目可以練習(xí)到循環(huán)加結(jié)構(gòu)體數(shù)組和ifelse的大量嵌套。

逆向這種東西就是一個(gè)經(jīng)驗(yàn)的積累,做得多了就會(huì)有感覺,這次的分析我會(huì)詳細(xì)寫一下如何判斷哪里是if哪里是while這種邏輯判斷。

題目描述

給你一個(gè)鏈表的頭節(jié)點(diǎn) head 和一個(gè)整數(shù) val ,請(qǐng)你刪除鏈表中所有滿足 Node.val == val 的節(jié)點(diǎn),并返回 新的頭節(jié)點(diǎn) 。

debug版匯編代碼

004E3580  push        ebp  
004E3581  mov         ebp,esp 
004E3583  sub         esp,0D8h 
004E3589  push        ebx  
004E358A  push        esi  
004E358B  push        edi  
004E358C  lea         edi,[ebp-0D8h] 
004E3592  mov         ecx,36h 
004E3597  mov         eax,0CCCCCCCCh 
004E359C  rep stos    dword ptr es:[edi]                 //下面是業(yè)務(wù)代碼
004E359E  mov         eax,dword ptr [head] 
004E35A1  mov         dword ptr [cur],eax      //cur = head;
004E35A4  mov         dword ptr [prev],0             //prev = 0;
004E35AB  cmp         dword ptr [cur],0             //cur != 0,這里可以看出來應(yīng)該是一個(gè)while或者if
004E35AF  je          removeElements+0A8h (4E3628h) //跳出while
004E35B1  mov         eax,dword ptr [cur]         
004E35B4  mov         ecx,dword ptr [eax]         //熟悉的取指針的內(nèi)容
004E35B6  cmp         ecx,dword ptr [val]         //這是判斷if(cur.filed1 == val)
004E35B9  jne         removeElements+97h (4E3617h) //跳到else
004E35BB  mov         eax,dword ptr [cur] 
004E35BE  cmp         eax,dword ptr [head]   //if(cur==head),同上這又是個(gè)ifelse
004E35C1  jne         removeElements+6Ah (4E35EAh) 
004E35C3  mov         eax,dword ptr [cur] 
004E35C6  mov         ecx,dword ptr [eax+4]         //ecx = cur->field2
004E35C9  mov         dword ptr [head],ecx             //head = cur->field2
004E35CC  mov         esi,esp 
004E35CE  mov         eax,dword ptr [cur] 
004E35D1  push        eax  
004E35D2  call        dword ptr [__imp__free (4E834Ch)] //這里應(yīng)該是調(diào)用了free
004E35D8  add         esp,4 
004E35DB  cmp         esi,esp 
004E35DD  call        @ILT+335(__RTC_CheckEsp) (4E1154h) 
004E35E2  mov         eax,dword ptr [head]                 //eax = head
004E35E5  mov         dword ptr [cur],eax             //cur = head
004E35E8  jmp         removeElements+95h (4E3615h) 
004E35EA  mov         eax,dword ptr [prev] //這里是else
004E35ED  mov         ecx,dword ptr [cur]     //ecx = cur,eax = prev
004E35F0  mov         edx,dword ptr [ecx+4] //edx = cur.field2
004E35F3  mov         dword ptr [eax+4],edx //prev.field2 = cur.field2
004E35F6  mov         esi,esp 
004E35F8  mov         eax,dword ptr [cur] 
004E35FB  push        eax  
004E35FC  call        dword ptr [__imp__free (4E834Ch)]     //這里應(yīng)該是調(diào)用了free
004E3602  add         esp,4 
004E3605  cmp         esi,esp 
004E3607  call        @ILT+335(__RTC_CheckEsp) (4E1154h) 
004E360C  mov         eax,dword ptr [prev] 
004E360F  mov         ecx,dword ptr [eax+4] 
004E3612  mov         dword ptr [cur],ecx             //cur = prev->field2
004E3615  jmp         removeElements+0A6h (4E3626h) //從這里可以看出來是一個(gè)if~else
004E3617  mov         eax,dword ptr [cur]         
004E361A  mov         dword ptr [prev],eax         //prev = cur
004E361D  mov         eax,dword ptr [cur]         
004E3620  mov         ecx,dword ptr [eax+4]     //cur.field2
004E3623  mov         dword ptr [cur],ecx         /cur = cur.filed2 
004E3626  jmp         removeElements+2Bh (4E35ABh) //這里是while的結(jié)尾
004E3628  mov         eax,dword ptr [head]         //出了while
004E362B  pop         edi  
004E362C  pop         esi  
004E362D  pop         ebx  
004E362E  add         esp,0D8h 
004E3634  cmp         ebp,esp 
004E3636  call        @ILT+335(__RTC_CheckEsp) (4E1154h) 
004E363B  mov         esp,ebp 
004E363D  pop         ebp  
004E363E  ret              

分析

  • 根據(jù)004E35AB行代碼可以看出這里是一個(gè)if或者while
  • 再看他跳到的004E3628的上一行是跳回到判斷所以可以判斷這一個(gè)大while
  • 一步一步看下去會(huì)看到004E35B6這一行發(fā)現(xiàn)是一個(gè)if判斷再看一下他判斷失敗時(shí)跳的位置
  • 失敗會(huì)跳到004E3617看他的上一行代碼004E3615 jmp removeElements+0A6h (4E3626h)
  • 可以看出來判斷就跳到下面的代碼!=就順序執(zhí)行然后跳過的代碼并出循環(huán)
  • 繼續(xù)看匯編代碼會(huì)看到好幾個(gè)這樣的if~else
struct tmp{
  DWORD val;
  DWORD tmpAddr;
};
struct tmp* func(DWORD head,DWORD val)
{
  cur = head;
  prev = 0;
  while(cur != 0){
    if(cur->filed1 == val){
      if(cur==head){
        head = cur->field2;
        free(cur);
        cur = head;
      }else{
        prev->field2 = cur->field2;
        free(cur);
        cur = prev->field2;
      }
    }else{
      prev = cur;
      cur = cur->field2;
    }
  }
  return head;
}

源代碼

* struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val){
    struct ListNode* cur = head, *prev = NULL;
    while(cur){
        if(cur->val == val){
            //頭刪
            if(cur == head){
               head = cur->next;//更新頭結(jié)點(diǎn)
               free(cur);//釋放存放val的節(jié)點(diǎn)
               cur = head;//更新當(dāng)前節(jié)點(diǎn)
           }
            //中間刪
            else{
               prev->next = cur->next;//鏈接
               free(cur);//釋放當(dāng)前為val的節(jié)點(diǎn)
               cur = prev->next;//更新當(dāng)前節(jié)點(diǎn)
           }
       }
       //不是val就往后遍歷
       else{
           prev = cur;
           cur = cur->next;
       }
    }
    return head;
}

到此這篇關(guān)于C++逆向分析移除鏈表元素實(shí)現(xiàn)方法詳解的文章就介紹到這了,更多相關(guān)C++移除鏈表元素內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在C++中如何阻止類被繼承詳解

    在C++中如何阻止類被繼承詳解

    這篇文章主要介紹了在C++中如何阻止類被繼承,對(duì)于C++初學(xué)者而言可以通過本文實(shí)例更好的理解類的原理及運(yùn)用,需要的朋友可以參考下
    2021-09-09
  • c++中std::placeholders的使用方法

    c++中std::placeholders的使用方法

    std::placeholders?是 C++ 標(biāo)準(zhǔn)庫中的一個(gè)工具,用于在函數(shù)對(duì)象綁定時(shí)創(chuàng)建占位符,本文就來詳細(xì)的介紹一下,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-02-02
  • C++實(shí)現(xiàn)俄羅斯方塊

    C++實(shí)現(xiàn)俄羅斯方塊

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)俄羅斯方塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • 標(biāo)準(zhǔn)C++類string的Copy-On-Write技術(shù)

    標(biāo)準(zhǔn)C++類string的Copy-On-Write技術(shù)

    這里,我想從C++類或是設(shè)計(jì)模式的角度為各位揭開Copy-On-Write技術(shù)在string中實(shí)現(xiàn)的面紗,以供各位在用C++進(jìn)行類庫設(shè)計(jì)時(shí)做一點(diǎn)參考
    2013-11-11
  • C++的智能指針你真的了解嗎

    C++的智能指針你真的了解嗎

    這篇文章主要為大家詳細(xì)介紹了C++的智能指針,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 使用C語言實(shí)現(xiàn)掃雷小游戲

    使用C語言實(shí)現(xiàn)掃雷小游戲

    這篇文章主要為大家詳細(xì)介紹了使用C語言實(shí)現(xiàn)掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C++中constexpr與模板元編程的基礎(chǔ)、常見問題、易錯(cuò)點(diǎn)及其規(guī)避策略

    C++中constexpr與模板元編程的基礎(chǔ)、常見問題、易錯(cuò)點(diǎn)及其規(guī)避策略

    C++編譯時(shí)計(jì)算允許程序在編譯階段完成計(jì)算任務(wù),constexpr與模板元編程是C編譯時(shí)計(jì)算的兩把利劍,它們不僅能夠提升程序的性能,還能增強(qiáng)代碼的健壯性和可維護(hù)性,通過避開本文闡述的易錯(cuò)點(diǎn),開發(fā)者可以更加得心應(yīng)手地運(yùn)用這些特性,編寫出既高效又優(yōu)雅的C代碼
    2024-06-06
  • 一個(gè)string類的簡單實(shí)現(xiàn)案例

    一個(gè)string類的簡單實(shí)現(xiàn)案例

    下面小編就為大家?guī)硪黄粋€(gè)string類的簡單實(shí)現(xiàn)案例。小編覺得挺不錯(cuò)的現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • C語言中sizeof()與strlen()函數(shù)的使用入門及對(duì)比

    C語言中sizeof()與strlen()函數(shù)的使用入門及對(duì)比

    這篇文章主要介紹了C語言中sizeof()與strlen()函數(shù)的使用入門及對(duì)比,同時(shí)二者在C++中的使用情況也基本上同理,是需要的朋友可以參考下
    2015-12-12
  • C++利用ImGUI繪制D3D外部菜單

    C++利用ImGUI繪制D3D外部菜單

    ImGUI 它是與平臺(tái)無關(guān)的C++輕量級(jí)跨平臺(tái)圖形界面庫,沒有任何第三方依賴,可以將ImGUI的源碼直接加到項(xiàng)目中使用。本文將利用ImGUI繪制D3D外部菜單,需要的可以參考一下
    2022-09-09

最新評(píng)論

河源市| 瑞金市| 积石山| 栾城县| 平度市| 灌南县| 威远县| 宁河县| 若尔盖县| 南漳县| 竹山县| 阿坝| 锡林浩特市| 图木舒克市| 清丰县| 房山区| 三穗县| 广东省| 车险| 年辖:市辖区| 乐昌市| 通河县| 赣州市| 五寨县| 常熟市| 新郑市| 淄博市| 射阳县| 乐山市| 普定县| 红安县| 茂名市| 璧山县| 宝丰县| 龙井市| 穆棱市| 中山市| 陆川县| 太谷县| 左云县| 花莲县|