Tag: assembly

这个汇编声明是什么意思?

我正在使用-s标志查看gcc生成的汇编代码。 一些陈述如下所示。 movl is_leader(%rip), destination 这里, is_leader是C代码中int类型的全局定义变量。 我不明白的是这里的术语是is_leader(%rip) 。 是不是翻录指令指针? 我需要知道这个语句是如何用来访问is_leader的 。

在C和C ++中调用函数时EAX寄存器初始化的差异

当编译为C程序或C ++程序(对于Linux x86-64)时,小程序的程序集之间存在奇怪的差异。 有问题的代码: int fun(); int main(){ return fun(); } 将其编译为C程序(使用gcc -O2 )可以得到: main: xorl %eax, %eax jmp fun 但是将其编译为C ++程序(使用g++ -02 )会产生: main: jmp _Z3funv 我觉得很困惑,C版本用0 ( xorl %eax, %eax )初始化主函数的返回值。 C语言的哪个特性对这种必要性负责? 编辑:对于int fun(void);来说确实如此int fun(void); 没有初始化eax寄存器。 如果根本没有fun原型,即: int main(){ return fun(); } 然后C编译器再次将eax寄存器归零。

内联汇编跳转错误

一旦Masm达到jmp,为什么会失败呢? struct gdt_entry { unsigned short limit_low; unsigned short base_low; unsigned char base_middle; unsigned char access; unsigned char granularity; unsigned char base_high; }; struct gdt_ptr { unsigned short limit; unsigned int base; }; struct gdt_entry gdt[3]; struct gdt_ptr gp; void gdt_flush() { __asm{ lgdt [gp] mov ax, 0x10 mov ds, ax mov es, ax mov […]

为什么静态变量的地址相对于指令指针?

我正在按照本教程关于assembly。 根据教程(我也在本地尝试,并得到类似的结果),以下源代码: int natural_generator() { int a = 1; static int b = -1; b += 1; /* (1, 2) */ return a + b; } 编译到这些汇编指令: $ gdb static (gdb) break natural_generator (gdb) run (gdb) disassemble Dump of assembler code for function natural_generator: push %rbp mov %rsp,%rbp movl $0x1,-0x4(%rbp) mov 0x177(%rip),%eax # (1) add […]

x86代码从x64进程注入x86进程

我意识到标题有点令人费解,所以让我解释一下我要做的事情: 我刚刚编写了一个简单的DLL注入器,用于我正在尝试编写的概念certificate。 该程序获取当前进程的快照,枚举进程树,并将DLL注入其直接父进程。 现在,在理想条件下,工作正常:32位版本的注入器可以注入到32位父进程中,64位版本的注入器可以注入到64位父进程中。 不过,我现在要做的是从x64注入器向32位父进程注入32位DLL。 一旦注入了DLL,我就希望再注入一个由注入的DLL导出的函数。 不过,我不确定是否真的可以做到。 (我已经汇总了一些代码来确定父进程是32位进程还是64位进程,所以这不是问题) 现在,我已经找到了一些代码,它们似乎通过将预编译的机器代码注入到流程中来完成第一部分。 (至少,我认为这就是它正在做的事情)通常,在注入对LoadLibraryW的调用之后,我将获得该调用返回的地址,将相对偏移量添加到我想要调用的导出函数,并注入一个调用function。 在这种情况下,我无法将32位库加载到我的64位注入器中,因此我无法像通常那样使用GetProcAddress找到函数的相对偏移量。 我通过以下方式解决了这个问题: 由于我无法使用常规方法找到32位DLL的函数偏移量,因此我正在将文件读入缓冲区,使用该缓冲区填充IMAGE_NT_HEADERS32结构,并枚举IMAGE_EXPORT_DIRECTORY以查找名称和相对偏移量所有导出的function。 所以在这一点上,我有以下内容: 32位DLL加载到32位进程中 在32位进程中运行以下代码时,该值等效于funcAddr: 码: HMODULE hInjectedDLL = LoadLibrary(“mydll.dll”); DWORD funcAddr = (DWORD)GetProcAddress(hInjectedDLL, “ExportedFunc”) – (DWORD)hInjectedDLL; 从理论上讲,我现在需要的只是hInjectedDLL的值,我应该可以调用该函数。 但遗憾的是,我对组装或机器代码知之甚少,知道如何获得该值。 有任何想法吗? (另外,我知道通过编译两个版本的注入器可以省去很多麻烦,当父进程的处理器架构不匹配时,让一个运行另一个版本。我试图避免去不过这条路线。) 编辑 :想想它可能有助于解释我在这个概念certificate中实际想要完成的事情。 我正在尝试一个想法,我必须允许在当前控制台中执行子进程,而不需要原始进程等待子进程完成。 由于在控制台应用程序中没有用于执行此操作的内置API,因此您通常会遇到一个进程树,所有进程都在等待各自的子进程完成。 为了实现此function,我想执行以下操作: 注射 DLL注入器将扮演“执行进程”的角色。 (通常必须等到子进程完成的进程)运行时,它确定其父进程的平台,以及父进程是否甚至是基于控制台的应用程序。 如果不是,则该过程仅使用exec系列函数来运行所需的子进程,立即退出。 如果父进程是控制台应用程序,则进程确定要使用的DLL,挂起最初创建注入进程的线程,然后将DLL注入父进程。 解决我们的职能 一旦DLL就位,注入器就会确定DLL导出的函数的地址。 (通常,我通过调用CreateRemoteThread来执行初始注入,然后在该线程上使用GetExitCodeThread来获取父进程中DLL的基址。一旦我有了这个,就可以通过简单的算法找到地址我们导出的函数,然后我可以使用它来注入该函数的第二次调用。 呼唤我们的function 导出的函数将类似于: BOOL RewriteHProcess(HANDLE hProcess) 注入器将再次使用CreateRemoteThread从父进程的上下文调用此函数,其中hProcess是注入器进程的句柄。 在DLL方面,该函数会做两件事之一(我不太确定我的第一个想法是否可行,考虑到跨线程的内存访问的安全限制,所以我把第二个想法放在一起,如果首先没有成功。) RewriteHProcess将打开先前挂起的线程进行读写,并使用ReadProcessMemory ,它将在进程的内存中搜索HANDLE到我们的注入器进程。 (我们假设父进程当前正在阻止使用WaitForSingleObject函数进一步执行。我知道命令提示符至少会执行,而这是我目前关注的焦点)然后DLL调用内部函数创建我们想要的子进程,关闭旧句柄,并使用新子进程的句柄覆盖内存。 […]

测量执行单个指令的时间

有没有办法使用C或汇编程序甚至C#来准确衡量执行ADD指令所需的时间?

写蹦床function

我已设法覆盖内存中函数的前几个字节,并将其绕过我自己的函数。 我现在遇到创建蹦床function以将控制反弹回真实function的问题。 这是我的问题的第二部分。 BYTE *buf = (BYTE*)VirtualAlloc(buf, 12, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); void (*ptr)(void) = (void (*)(void))buf; vm_t* VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *), vmInterpret_t interpret ) { MessageBox(NULL, L”Oh Snap! VM_Create Hooked!”, L”Success!”, MB_OK); ptr(); return NULL;//control should never get this far } void Hook_VM_Create(void) { DWORD dwBackup; VirtualProtect((void*)0x00477C3E, 7, PAGE_EXECUTE_READWRITE, &dwBackup); //save […]

GMP如何以任意数量的字节存储其整数?

2 ^ 64离我的ram /硬盘驱动器可以处理的“无限”还有一段距离…… 首先,我想知道GMP如何与内存/处理器一起工作,因为它做了一些阴暗的优化…… 我还想知道是否有一种方法可以在任意数量的字节上存储整数(无符号,更容易)。 例如,在50个字节上,我的上限为2 ^ 400 -1。 要做的事情是使用携带以保持数字从一个字节到另一个字节保持一致,我对此有一些了解,但我真的不确定这是否是最快的方法。 我甚至不确定我是否正确。 我猜GMP使用这种方式来存储它的数据,但我只想要一些(甚至很少)解释或某些理论转发(我没有任何博士学位,所以不要太难)。

%C在GCC内联汇编代码中的含义是什么?

我试图理解这个来自_hypercall0内联汇编代码。 asm volatile (“call hypercall_page+%c[offset]” \ : “=r” (__res) \ : [offset] “i” (__HYPERVISOR_##name * sizeof(hypercall_page[0])) \ : “memory”, “edi”, “esi”, “edx”, “ecx”, “ebx”, “eax”) 我无法找到第一行中%c的含义的信息。 我没有在GCC手册最明显的部分找到任何信息,这解释了%[name] ,但没有找到%c[name] 。 还有其他我应该看的地方吗?

rdtsc,周期太多了

#include static inline unsigned long long tick() { unsigned long long d; __asm__ __volatile__ (“rdtsc” : “=A” (d) ); return d; } int main() { long long res; res=tick(); res=tick()-res; printf(“%d”,res); return 0; } 我用gcc编译了这段代码-O0 -O1 -O2 -O3优化。 我总是得到2000-2500个周期。 任何人都可以解释这个输出的原因吗? 如何度过这些周期? 第一个函数“tick”是错误的。 这是对的 。 另一个版本的function“滴答” static __inline__ unsigned long long tick() { unsigned hi, lo; […]