七月份,我投了YY的一份的实习生简历,由于我准备不足,有一些问题没有回答出来,下面我就将电话面试的问题总结一下,对自己不懂得问题进行了一些研究,希望也能给大家提供一些经验和帮助。

问题一:堆栈平衡的原理是什么

当问到这个问题的时候,我想到的就是堆栈平衡,但是他就问到原理是什么的时候,我就答不出来了,在结束之后我在百度下寻找,明白了其中的原理下面我就来说明一下

我的理解,其实堆栈平衡就是程序的调用。我们先来复习一下汇编的指令

call指令

1.向堆栈中压入下一行的地址,esp-4

2.jmp到call的子程序地址

ret指令

1.将esp+4,即将堆栈中的值出栈

2.jmp dword ptr ds:[esp-4],即jmp到当前的位置

知道了基础之后,我们就可以通过一个例子进行描述,我选择了一个upx的壳,壳的入口点的各个寄存器的值,pushad将各个寄存器的值压入栈中

<pre name="code" class="plain">EAX 00000000
ECX 0012FFB0
EDX 7C92E4F4 ntdll.KiFastSystemCallRet
EBX 7FFD3000
ESP 0012FFC4
EBP 0012FFF0
ESI 0012B5D0
EDI 005A7908
EIP 0040E8C0 UPX.<ModuleEntryPoint>
C 0  ES 0023 32位 0(FFFFFFFF)
P 1  CS 001B 32位 0(FFFFFFFF)
A 0  SS 0023 32位 0(FFFFFFFF)
Z 1  DS 0023 32位 0(FFFFFFFF)
S 0  FS 003B 32位 7FFDF000(FFF)
T 0  GS 0000 NULL
D 0
O 0  LastErr ERROR_NO_IMPERSONATION_TOK

到达OEP时各个寄存器的变化

<pre name="code" class="plain">EAX 00000000
ECX 0012FFB0
EDX 7C92E4F4 ntdll.KiFastSystemCallRet
EBX 7FFD3000
ESP 0012FFC4
EBP 0012FFF0
ESI 0012B5D0
EDI 005A7908
EIP 004010CC UPX.004010CC
C 0  ES 0023 32位 0(FFFFFFFF)
P 1  CS 001B 32位 0(FFFFFFFF)
A 0  SS 0023 32位 0(FFFFFFFF)
Z 1  DS 0023 32位 0(FFFFFFFF)
S 0  FS 003B 32位 7FFDF000(FFF)
T 0  GS 0000 NULL
D 0
O 0  LastErr ERROR_NO_IMPERSONATION_TOK

我们发现是不是除了eax,其他的值都一样,因为eax保存了当前oep的值,所以eax有变化

pushed

0040E8C0 >  60              pushad
0040E8C1    BE 15B04000     mov esi,UPX.0040B015

将各个寄存器的数据压栈,其结果如下:

<pre name="code" class="plain">EDI 005A7908
ESI 0012B5D0
EBP 0012FFF0
ESP 0012FFC4
EBX 7FFD3000
EDX 7C92E4F4
ECX 0012FFB0
EAX 00000000

popad

0040E8C0 >  60              pushad
0040E8C1    BE 15B04000     mov esi,UPX.0040B015

结果就是到达oep时的各个寄存器的值
这个时候我想大家就明白了,其实ESP定律就是完成了一次调用子程序的过程。在这里关键的地方是:如果我们要返回父程序,则当我们在堆栈中进行堆栈的操作的时候,一定要保证在RET这条指令之前,ESP指向的是我们压入栈中的地址

问题二:全局变量在堆栈中的变化

下面这段代码是我在VC++6.0进行调试时进入反汇编代码是遇到的,我发现不管什么样的函数,都有这样的一段代码,上网查询发现他是函数框架,也就说这个框架是函数执行时必须的

esp指向的地方就是堆栈

00401020   push        ebp   /ESP-4,并将ebp的值写入esp内存中
00401021   mov         ebp,esp  /esp的值付给ebp
00401023   sub         esp,40h  /开辟一个40h大的空间
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h   /循环10次
00401031   mov         eax,0CCCCCCCCh  /eax的值为0xCCCCCCCCh
00401036   rep stos    dword ptr [edi] /ESP+4,重复将EAX的值付给edi的内存中
8:        return 0;
00401038   xor         eax,eax   /eax清零
9:    }
0040103A   pop         edi
0040103B   pop         esi
0040103C   pop         ebx
0040103D   mov         esp,ebp
0040103F   pop         ebp
00401040   ret
#include "stdafx.h"
int fun()
{return 0;
}
int main(int argc, char* argv[])
{fun();return 0;
}

我们画出他的堆栈变化示意图:

0018FEA0  40 FF 18 00  @...     /push ebx
0018FEA4  80 10 40 00  ..@.    /push esi

0018FEA8  00 E0 FD 7F  .帻.   /push edi
0018FEAC  CC CC CC CC  烫烫
0018FEB0  CC CC CC CC  烫烫
0018FEB4  CC CC CC CC  烫烫
0018FEB8  CC CC CC CC  烫烫
0018FEBC  CC CC CC CC  烫烫
0018FEC0  CC CC CC CC  烫烫
0018FEC4  CC CC CC CC  烫烫
0018FEC8  CC CC CC CC  烫烫
0018FECC  CC CC CC CC  烫烫
0018FED0  CC CC CC CC  烫烫
0018FED4  CC CC CC CC  烫烫
0018FED8  CC CC CC CC  烫烫
0018FEDC  CC CC CC CC  烫烫
0018FEE0  CC CC CC CC  烫烫
0018FEE4  CC CC CC CC  烫烫
0018FEE8  CC CC CC CC  烫烫
0018FEEC  40 FF 18 00  @...    /push ebp

我们会发现这是一个循环的过程,esp-40h开辟出一个空间,eax的值将所开辟的内存值都赋值0xCCCCCCCC,这个想明白的话,那变量是如何变换的也就简单了,我们只需要在函数中赋值相应的变量,参数或者表达式就可以了。

#include "stdafx.h"
int fun2(int a,int b)
{return a+b;
}
int fun1(int a,int b)
{fun2(5,6);return a+b;}
int fun(int a,int b)
{int r;r=a+b;fun1(3,4);return 0;
}
int main(int argc, char* argv[])
{fun(1,2);return 0;
}

VC++6.0部分的汇编代码:

15:   int fun(int a,int b)
16:   {
004010B0   push        ebp
004010B1   mov         ebp,esp
004010B3   sub         esp,44h
004010B6   push        ebx
004010B7   push        esi
004010B8   push        edi
004010B9   lea         edi,[ebp-44h]
004010BC   mov         ecx,11h
004010C1   mov         eax,0CCCCCCCCh
004010C6   rep stos    dword ptr [edi]
17:       int r;
18:       r=a+b;
004010C8   mov         eax,dword ptr [ebp+8]
004010CB   add         eax,dword ptr [ebp+0Ch]
004010CE   mov         dword ptr [ebp-4],eax
19:       fun1(3,4);
004010D1   push        4
004010D3   push        3
004010D5   call        @ILT+5(fun1) (0040100a)
004010DA   add         esp,8
20:       return 0;
004010DD   xor         eax,eax

我们在VC中进入调试就会发现一个重要的变化      ebp-4的位置为第一个变量的位置,ebp+8的位置为第一个参数的位置,大家可以自己画一下堆栈图,而且每一个函数都和我上面所说框架的相同,而且是循环的。而我以前从来没有注意到 ,面试就吃亏了。

当然了问题不只是这两个,还有对软件破解的流程,脱壳的方法,以及用c语言编写过那些东西等等。我的编程能力并不是特别的好,所以在c语言上的问题也没有回答好。这次的面试也给我很大的启发   1.学习要注重深度,而非广度,原理性的知识要弄懂,不可一知半解。2.复习c语言,对c语言不仅要会用,这要理解函数背后的运行原理。所以接下来还要继续努力。

记YY的一次面试经历相关推荐

  1. 记一次海康威视的面试经历

    参加的岗位为 数据平台-云计算开发工程师 面试有两次,第一次是技术面试,有两位 个人感觉一位是技术人员,一位是类似项目经理的人员. 面试内容包括之前的项目,k8s的相关内容.容器网络.多进程,多线程, ...

  2. 记2016.10.15百度面试经历,软件研发工程师

    9月参加的网上笔试,选择主要做了一些行测的题(头一次做行测题),后面有三道编程题,做出来一道,卡在第二道了50%,感觉自己水水的,百度也一直没通知面试,以为被刷了就没抱什么希望.后来13号竟然发来了面 ...

  3. (四)记一次人生第一次面试经历,快来查阅

    一.话题渲染 有天上课,突然发现辅导员在年级群发了一则招聘信息,是关于广州富米科技有限公司的.我看到该公司也在招聘校园大使,主要负责宣讲会那天协助现场的.于是乎,我就果断地联系上了负责人,并争取机会, ...

  4. 记一下金山云实习生面试经历

    简要说下流程先== 一面 1  自我介绍 2 因为还在职所以问了一下目前做的项目,具体了解了下底层是什么实现,我的任务是什么,以及遇到的一些问题. 3 针对简历问一下对linux的理解程度怎么样,使用 ...

  5. 记一次欢聚时代面试经历

    上个星期受邀请到欢聚时代面试,坐了一个小时左右的地铁并且找了好一会儿才找到欢聚时代的大厦.欢聚时代有一层楼专门作为面试使用的,环境很好,设计有特色和艺术感.在沙发上等了一会儿,就遇到了面试官,看起来3 ...

  6. 面试经历—广州YY(欢聚时代)

    转载自   面试经历-广州YY(欢聚时代) 上周去YY(欢聚时代)面试JAVA工程师,现在回忆一下当时的面试过程,面试问的问题有: 1.常用的集合类 HashMap.HashTable.ArrayLi ...

  7. 【行走的Offer收割机】记一位朋友斩获BAT技术专家Offer的面试经历

    点击上方"蓝字", 右上角选择"设为星标" 周一至五早11点半!精品文章准时送上! 本文转载自公众号:石杉的架构笔记 概述 本文我们通过一篇真实的一线面经,带大 ...

  8. 记一次蚂蚁金服面试经历

    蚂蚁金服大数据数仓岗位的面试经历 一.前言 本人一直在外企做传统数仓也差不多十年了,技术栈都是以关系型数据库和商业工具为主.看着日新月异的大数据技术的发展和数仓架构的不断迭代,想跳到互联网企业看看去接 ...

  9. 记第一次实习面试经历(字节跳动)

    想要获取笔者自己整理的Android.Java面试资料原文文稿(markdown格式),可关注左边栏二维码所示公众号,公众号内回复"A3"(Android资料)."J4& ...

  10. 记工作一年后腾讯社招面试经历

    腾讯社招面试经历 电话面试 在某招聘APP投了腾讯一个C++后台开发岗位后,收到电面邀请,时间是晚上7点半.当时还没下班,提前跑到办公楼外面接电话.主要问了一些语言.数据结构方面的基础知识,聊了将近5 ...

最新文章

  1. epoch,iteration,batch,batch_size
  2. 51Nod-1136 欧拉函数【数论】
  3. AlarmManager深入浅出
  4. java递归实现多级菜单栏_vue+ java 实现多级菜单递归效果
  5. java 高级网络编程_java高级网络编程—客户端与服务器
  6. 瑞银报告 | 美国银行业科技支出:凡有的,还要加给他,叫他有余...
  7. 《Python游戏趣味编程》 第4章 疯狂的小圆圈
  8. vue的UI框架之有赞移动端vant-ui
  9. Standford Moss。图形用户页面接口,代码查重
  10. 8.7.1. Declaration of Enumerated Types
  11. 毕业就去当网红?先听听8位95后网红的口述
  12. int和Integer有什么区别
  13. 《google软件测试之道》精彩语句摘抄
  14. python中dic的操作
  15. 获取Golang环境变量的三种方式
  16. JavaScript实现React实现网页转换成图片截屏下载
  17. python marshal loads failed_Python模块学习:marshal 对象的序列化
  18. uview u-popup设置背景透明
  19. 一成电计算机考研国家线2O 9,【九〇六 | 打卡】考研“国家线”只是起点,我们要挑战骇浪惊涛!...
  20. 小程序学习与实践(一)

热门文章

  1. 【OpenGL】OpenGL帧缓存对象(FBO:Frame Buffer Object)
  2. Android常用的开源库收集(持续更新中)
  3. python游走代码_用Python模拟随机游走(Random walks)
  4. UT2016学习笔记
  5. js 生成20内加减法(大概率是用于验证码)
  6. Kryo官方文档学习笔记
  7. matlab自动调焦,光学系统离焦对自动调焦评价函数的影响
  8. 【模糊回归预测】基于matlab萤火虫算法优化模糊神经网络回归预测【含Matlab源码 2034期】
  9. MongoDB查询命令详解
  10. vue实现动态二维码完成签到功能