我正在编写代码来临时使用我自己的堆栈进行实验.这在我使用文字内联汇编时起作用.我将变量位置硬编码为ebp的偏移量.但是,我希望我的代码可以不用硬编码内存地址,所以我一直在研究GCC的扩展内联汇编.我所拥有的是以下内容:
volatile intptr_t new_stack_ptr = (intptr_t) MY_STACK_POINTER;
volatile intptr_t old_stack_ptr = 0;
asm __volatile__("movl %%esp, %0\n\t"
"movl %1, %%esp"
: "=r"(old_stack_ptr) /* output */
: "r"(new_stack_ptr) /* input */
);
Run Code Online (Sandbox Code Playgroud)
这一点是首先将堆栈指针保存到变量old_stack_ptr中.接下来,堆栈指针(%esp)将被我在new_stack_ptr中保存的地址覆盖.
尽管如此,我发现GCC将%esp保存到old_stack_ptr中,但是没有用new_stack_ptr替换%esp.经过深入检查,我发现它实际上扩展了我的程序集并添加了它自己的指令,如下所示:
mov -0x14(%ebp),%eax
mov %esp,%eax
mov %eax,%esp
mov %eax,-0x18(%ebp)
Run Code Online (Sandbox Code Playgroud)
我认为GCC正试图保留%esp,因为我没有将它明确声明为"输出"操作数......我可能完全错了...
我真的很想使用扩展的内联汇编来实现这一点,因为如果没有,似乎我必须将%ebp的位置偏移"硬编码"到程序集中,我宁愿使用像这样的变量名.特别是因为这个代码需要在几个不同的系统上工作,这些系统似乎都以不同的方式抵消了我的变量,所以使用扩展的内联汇编允许我明确地说出变量位置......但是我不明白为什么它会这样做额外的东西,不要让我像以前一样覆盖堆栈指针,自从我开始使用扩展程序集以来,它一直在这样做.
我感谢任何帮助!
我正在非常困难地追踪下面的二进制炸弹的汇编代码(从学校分配炸弹必须被拆除,这个炸弹包含6个阶段,所有阶段都有1个正确的输入以进入下一个阶段).我目前在phase_4上,它有一个名为func4的递归函数.我已经确定输入是"%d%d",这是两个整数.但是,即使在每个步骤中获取所有寄存器的信息之后,我也无法弄清楚func4正在做什么.
Phase_4:
(gdb) disas
Dump of assembler code for function phase_4:
=> 0x08048e24 <+0>: sub $0x2c,%esp
0x08048e27 <+3>: lea 0x1c(%esp),%eax
0x08048e2b <+7>: mov %eax,0xc(%esp)
0x08048e2f <+11>: lea 0x18(%esp),%eax
0x08048e33 <+15>: mov %eax,0x8(%esp)
0x08048e37 <+19>: movl $0x804a7f1,0x4(%esp)
0x08048e3f <+27>: mov 0x30(%esp),%eax
0x08048e43 <+31>: mov %eax,(%esp)
0x08048e46 <+34>: call 0x80488d0 <__isoc99_sscanf@plt>
0x08048e4b <+39>: cmp $0x2,%eax
0x08048e4e <+42>: jne 0x8048e5d <phase_4+57>
0x08048e50 <+44>: mov 0x18(%esp),%eax
0x08048e54 <+48>: test %eax,%eax
0x08048e56 <+50>: js 0x8048e5d <phase_4+57>
0x08048e58 <+52>: cmp $0xe,%eax
0x08048e5b <+55>: jle 0x8048e62 <phase_4+62> …
Run Code Online (Sandbox Code Playgroud) I want to use gdb to see my GDTR/LDTR/TTR and segment register
Run Code Online (Sandbox Code Playgroud)
不可见部分(x86)所以在gdb中我输入“p/x $gdtr”...等但结果是“$6 = Value can't be convert to integer”,在gdb中我输入“p/x $cs”唯一的结果是 CS,只是可见的部分
can anyone tell me how to view these value??
Run Code Online (Sandbox Code Playgroud)
感谢您的回答
我正在学习如何溢出缓冲区。我很难覆盖回信地址。这是我试图利用的易受攻击的代码:
(gdb) disas main
Dump of assembler code for function main:
0x0804845b <+0>: push ebp
0x0804845c <+1>: mov ebp,esp
0x0804845e <+3>: sub esp,0x100
0x08048464 <+9>: mov eax,DWORD PTR [ebp+0xc]
0x08048467 <+12>: add eax,0x4
0x0804846a <+15>: mov eax,DWORD PTR [eax]
0x0804846c <+17>: push eax
0x0804846d <+18>: call 0x8048340 <strlen@plt>
0x08048472 <+23>: add esp,0x4
0x08048475 <+26>: mov edx,eax
0x08048477 <+28>: mov eax,DWORD PTR [ebp+0xc]
0x0804847a <+31>: add eax,0x4
0x0804847d <+34>: mov eax,DWORD PTR [eax]
0x0804847f <+36>: push edx
0x08048480 <+37>: push eax …
Run Code Online (Sandbox Code Playgroud) #include <stdio.h>
int main(){
__asm__ (
"result: \n\t"
".long 0 \n\t"
"rdtsc \n\t"
"movl %eax, %ecx\n\t"
"rdtsc \n\t"
"subl %ecx, %eax\n\t"
"movl %eax, result\n\t"
);
extern int result;
printf("%d\n", result);
}
Run Code Online (Sandbox Code Playgroud)
我想从汇编的一些数据传递到main
通过result
变量.这可能吗?我的汇编代码导致了Segmentation fault (core dumped)
.我使用的是Ubuntu 15.10 x86_64,gcc 5.2.1.
我正在尝试使用Visual Studio 2015中的Xamarin.Forms为IOS应用程序执行发布构建.
在应用程序属性中的iOS Build菜单下,如果我仅设置链接器行为链接SDK程序集或链接所有程序集 - 我收到以下构建错误:
无法解析组件: 'System.Net.Http.Primitives,版本= 1.5.0.0,文化=中性公钥= b03f5f7f11d50a3a' BlackhawkPlatform.App.iOS
如果我没有链接任何程序集 - 应用程序构建正常但输出ipa超过40mb大0未压缩超过100mb因此无法提交到iTunes Connect.
我安装了最新版本的System.Net客户端库和Xamarin Forms.
我试图通过使用--linkskip=System.Net.Http.Primitives
附加mtouch参数框中的命令跳过程序集链接但该dos不起作用.
知道我怎么能绕过这个吗?
这个问题是关于cmp
装配的指令.我无法理解我的书如何推断SF
和OF
旗帜.
cmp vleft, vright
Run Code Online (Sandbox Code Playgroud)
根据我的书:对于有符号整数,有三个重要的(ZF)
标志:零标志,溢出(OF)
标志和标志(SF)
标志.如果操作结果溢出(或下溢),则设置溢出标志.如果操作结果为负,则设置符号标志.如果vleft = vright
,ZF
则设置(就像无符号整数一样).如果vleft > vright
,ZF
是未设置的SF = OF
.如果vleft < vright
,ZF
是未设置的SF != OF
.不要忘记其他指令也可以改变FLAGS寄存器,而不仅仅是CMP
.
首先,让我们考虑一下这个vleft > vright
案子.我的书说如下:
如果vleft> vright,为什么SF = OF?如果没有溢出,则差异将具有正确的值,并且必须是非负的.因此,SF = OF = 0.但是,如果存在溢出,则差异将不具有正确的值(并且实际上将是负的).因此,SF = OF = 1.
第一部分我明白了SF = OF = 0
.例如,它可以是:
0111 - 0101 = 0111 + 1010 + 1 = 10010 …
我正在尝试使用以下代码加载MSIL程序集:
string PathOfDll = "PathOfMsILFile (Dll)";
Assembly SampleAssembly;
SampleAssembly = Assembly.LoadFrom(PathOfDll);
Run Code Online (Sandbox Code Playgroud)
在该程序的结尾,我应该删除该文件:
File.Delete(PathOfDll);
Run Code Online (Sandbox Code Playgroud)
它导致错误:'System.UnauthorizedAccessException'
Additional information: Access to the path 'Path' is denied .
Run Code Online (Sandbox Code Playgroud)
它与UAC无关,只是因为我在程序开始时加载程序集,而当我想手动删除它时,它表示该文件正在vshost.exe中使用。所以我说这只是为了表明它是用于组装的!
那么有什么方法可以摆脱它(类似于卸载此程序集)?
注意:我正在编写代码来运行垃圾收集器,但此问题仍未解决。
谢谢。
嗨,我正在使用 gcc 在 mac 上处理 ASM intel_syntax noprefix,出于某种原因,我在后端不断收到此错误:64 位模式不支持 32 位绝对寻址 这是否与变量有关,在时刻是否已在 ASM 上使用内联?
这是我的代码:
#include <stdio.h>
char c, b;
int main() {
printf("Give me letter: ");
scanf(" %c", &c);
_
_asm( ".intel_syntax noprefix;"
"xor eax, eax;" // clear eax
"mov al, byte ptr [c];" // save c in eax
"cmp eax, 65;" // eax ? "A"
"jl Fin;" // eax < "A" -> Fin
"cmp eax, 90;" // eax ? "Z"
"jg UpC;" // eax >= …
Run Code Online (Sandbox Code Playgroud)