Tag: x86 64

在x86-64平台上计算C(++)中64位无符号参数的(a * b)%m FAST?

我正在寻找一种快速方法来有效地计算uint64_t类型的a , b , n的模数n (在数学意义上)。 我可以忍受前提条件,例如n!=0 ,甚至a<n && b<n 。 请注意,C表达式(a*b)%n不会删除它,因为产品被截断为64位。 我正在寻找(uint64_t)(((uint128_t)a*b)%n)除了我没有uint128_t (我知道,在Visual C ++中)。 我正在使用Visual C ++(最好)或GCC / clang内部,充分利用x86-64平台上可用的底层硬件; 或者如果不能用于便携式inlinefunction。

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调用内部函数创建我们想要的子进程,关闭旧句柄,并使用新子进程的句柄覆盖内存。 […]

我怎么告诉gcc我的内联汇编是否是堆栈的一部分?

考虑这样的内联汇编: uint64_t flags; asm (“pushf\n\tpop %0” : “=rm”(flags) : : /* ??? */); 尽管可能存在某种内在函数来获取RFLAGS的内容,但我如何向编译器指出我的内联汇编在堆栈顶部破坏了一个四字内存?

虚假共享和primefaces变量

当不同的变量位于同一个缓存行中时,您可能会遇到False Sharing ,这意味着即使两个不同的线程(在不同的核心上运行)正在访问两个不同的变量,如果这两个变量位于同一个缓存行中,您将拥有性能命中,因为每次都会触发缓存一致性。 现在说这些变量是primefaces变量(primefaces我指的是引入内存栅栏的变量,比如C ++的atomic ),会在那里进行虚假共享,或者primefaces变量是否在同一个缓存行中并不重要或者不是,据说他们无论如何都会引入缓存一致性。 换句话说,将primefaces变量放在同一个缓存行中会使应用程序变慢而不是将它们放在同一个缓存行中吗?

在x64 Visual Studio中内联汇编函数

我知道x64模式下的MSVC编译器不支持内联汇编代码片段,并且为了使用汇编代码,你必须在一些外部my_asm_funcs.asm文件中定义你的函数,如下所示: my_asm_func PROC mov rax, rcx ret my_asm_func ENDP 然后在你的.c或.h文件中为这个函数定义一个标题: int my_asm_func(int x); 虽然该解决方案解决了许多问题,但我仍然有兴趣使汇编代码函数内联,换句话说 – 在编译之后我不想对my_asm_func进行任何“调用”,我只是希望这个程序集被粘合进入我的最终编译代码。 我尝试使用inline和__forceinline关键字声明函数 ,但似乎没有任何帮助。 还有什么办法可以做我想要的吗?

C – 在Mac OSX Lion上编译时,架构x86_64的未定义符号

我在Mac OSX Lion上编译一个非常简单的name.c文件时遇到了一些问题。 现在,我开始在cs50.net上关注哈佛CS50课程。 我不是全新的编程,但我很好奇这门课程的教学方式。 这是name.c的来源: #include #include int main(void) { printf(“State your name:\n”); string name = GetString(); printf(“O hai, %s!\n”, name); return 0; } 如您所见,它需要这个库: https : //manual.cs50.net/CS50_Library 。 现在,当我编译它时,会发生这种情况: Undefined symbols for architecture x86_64: “_GetString”, referenced from: _main in name-vAxcar.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with […]

矢量化模运算

我正在尝试编写一些合理快速的组件向量加法代码。 我正在使用(签名,我相信)64位整数。 function是 void addRq (int64_t* a, const int64_t* b, const int32_t dim, const int64_t q) { for(int i = 0; i < dim; i++) { a[i] = (a[i]+b[i])%q; // LINE1 } } 我正在使用icc -std=gnu99 -O3 (icc以便我以后可以使用SVML)在IvyBridge(SSE4.2和AVX,但不是AVX2)上进行编译。 我的基线是从LINE1中删除%q 。 使用dim=11221184 100(迭代)函数调用需要1.6秒。 ICC自动矢量化SSE代码; 大。 我真的想做模块化的补充。 使用%q ,ICC不会自动向量化代码,并且它在11.8秒(!)内运行。 即使忽略了之前尝试的自动矢量化,这似乎仍然过分。 由于我没有AVX2,因此使用SSE进行矢量化需要SVML,这也许就是ICC没有自动矢量化的原因。 无论如何,这是我尝试对内循环进行矢量化: __m128i qs = _mm_set1_epi64x(q); for(int i […]

如何将像素结构加载到SSE寄存器中?

我有一个8位像素数据的结构: struct __attribute__((aligned(4))) pixels { char r; char g; char b; char a; } 我想使用SSE指令来计算这些像素上的某些东西(即Paeth变换)。 如何将这些像​​素作为32位无符号整数加载到SSE寄存器中?

在x86中增量是一个整数primefaces?

在多核x86机器上,假设在core1上执行的线程增加一个整数变量a ,同时核心2上的线程也增加它。 假设a的初始值为0,那么它最终总是2吗? 或者它可能有其他价值? 假设a被声明为volatile并且我们没有使用primefaces变量(例如C ++的atomic 和gcc中的原子操作)。 如果在这种情况下a的值确实总是2,那是否意味着x86-64中的long int也具有相同的属性,即a到底总是2?

x86汇编:INC和DEC指令和溢出标志

在x86汇编中,当有符号整数上的add或sub操作溢出时,溢出标志置位;当无符号整数上的操作溢出时,置载标志置位。 但是,当涉及到inc和dec指令时,情况似乎有些不同。 根据该网站 , inc指令根本不影响进位标志。 但是我找不到有关inc和dec如何影响溢出标志的任何信息,如果有的话。 发生整数溢出时,是否设置inc或dec设置溢出标志? 对于有符号整数和无符号整数,这种行为是否相同? ============================= 编辑 ==================== ========= 好的,基本上这里的共识是,在设置标志方面,INC和DEC应该与ADD和SUB的行为相同,但进位标志除外。 这也是英特尔手册中的内容。 问题是,当涉及到无符号整数时,我实际上无法在实践中重现这种行为。 请考虑以下汇编代码(使用GCC内联汇编以便更轻松地打印结果。) int8_t ovf = 0; __asm__ ( “movb $-128, %%bh;” “decb %%bh;” “seto %b0;” : “=g”(ovf) : : “%bh” ); printf(“Overflow flag: %d\n”, ovf); 这里我们递减一个带符号的8位值-128。 由于-128是可能的最小值,溢出是不可避免的。 正如预期的那样,打印出: Overflow flag: 1 但是当我们使用无符号值执行相同操作时,行为并不像我预期的那样: int8_t ovf = 0; __asm__ ( “movb $255, %%bh;” […]