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

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

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

前言

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

逆向這種東西就是一個經驗的積累,做得多了就會有感覺,這次的分析我會詳細寫一下如何判斷哪里是if哪里是while這種邏輯判斷。

題目描述

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

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è)務代碼
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,這里可以看出來應該是一個while或者if
004E35AF  je          removeElements+0A8h (4E3628h) //跳出while
004E35B1  mov         eax,dword ptr [cur]         
004E35B4  mov         ecx,dword ptr [eax]         //熟悉的取指針的內容
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),同上這又是個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)] //這里應該是調用了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)]     //這里應該是調用了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) //從這里可以看出來是一個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的結尾
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行代碼可以看出這里是一個if或者while
  • 再看他跳到的004E3628的上一行是跳回到判斷所以可以判斷這一個大while
  • 一步一步看下去會看到004E35B6這一行發(fā)現(xiàn)是一個if判斷再看一下他判斷失敗時跳的位置
  • 失敗會跳到004E3617看他的上一行代碼004E3615 jmp removeElements+0A6h (4E3626h)
  • 可以看出來判斷就跳到下面的代碼!=就順序執(zhí)行然后跳過的代碼并出循環(huán)
  • 繼續(xù)看匯編代碼會看到好幾個這樣的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;//更新頭結點
               free(cur);//釋放存放val的節(jié)點
               cur = head;//更新當前節(jié)點
           }
            //中間刪
            else{
               prev->next = cur->next;//鏈接
               free(cur);//釋放當前為val的節(jié)點
               cur = prev->next;//更新當前節(jié)點
           }
       }
       //不是val就往后遍歷
       else{
           prev = cur;
           cur = cur->next;
       }
    }
    return head;
}

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

相關文章

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

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

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

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

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

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

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

    標準C++類string的Copy-On-Write技術

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論

广宁县| 电白县| 满洲里市| 磐石市| 昭通市| 瓦房店市| 仁化县| 庆阳市| 太仓市| 上高县| 天全县| 临夏县| 海晏县| 门源| 平谷区| 牙克石市| 日喀则市| 凤山市| 新营市| 蓬莱市| 江永县| 淄博市| 临澧县| 虞城县| 修武县| 明溪县| 阜新市| 汉沽区| 沿河| 洛浦县| 若尔盖县| 大理市| 康乐县| 乐清市| 鸡西市| 克拉玛依市| 江津市| 平乐县| 陵川县| 射洪县| 抚顺县|