具有内联汇编和访问c变量的多线程

具有内联汇编和访问c变量的多线程,c,multithreading,assembly,x86,brute-force,C,Multithreading,Assembly,X86,Brute Force,我使用内联汇编来构造一组密码,我将使用这些密码对给定的哈希进行暴力攻击。我将此用作构建密码的参考 这在单线程环境中可以完美地工作。它产生无限量的递增密码 因为我只有asm的基本知识,所以我理解这个想法。gcc使用ATT,因此我使用-masm=intel 在尝试对程序执行多线程时,我意识到这种方法可能不起作用。 下面的代码使用了2个全局C变量,我假设这可能就是问题所在 __asm__("pushad\n\t" "mov edi, offset plaintext\n\t" <----

我使用内联汇编来构造一组密码,我将使用这些密码对给定的哈希进行暴力攻击。我将此用作构建密码的参考

这在单线程环境中可以完美地工作。它产生无限量的递增密码

因为我只有asm的基本知识,所以我理解这个想法。gcc使用ATT,因此我使用
-masm=intel

在尝试对程序执行多线程时,我意识到这种方法可能不起作用。
下面的代码使用了2个全局C变量,我假设这可能就是问题所在

__asm__("pushad\n\t"
    "mov edi, offset plaintext\n\t" <---- global variable
    "mov ebx, offset charsetTable\n\t" <---- again
    "L1: movzx eax, byte ptr [edi]\n\t"
    "    movzx eax, byte ptr [charsetTable+eax]\n\t"
    "    cmp al, 0\n\t"
    "    je L2\n\t"
    "    mov [edi],al\n\t"
    "    jmp L3\n\t"
    "L2: xlat\n\t"
    "    mov [edi],al\n\t"
    "    inc edi\n\t"
    "    jmp L1\n\t"
    "L3: popad\n\t");

使用内联程序集块外部的互斥来保护此函数。

由于您已经在使用pthreads,另一个选项是将多个线程修改的变量转换为每线程变量(线程特定数据)。看见其工作方式如下:

在主线程中(在创建其他线程之前),执行以下操作:

然后在使用
纯文本
/
字符集
变量(或更多类似变量)的每个线程中,执行以下操作:

或者创建/使用多个键,每个变量一个;在这种情况下,您不会得到
str
container/double indirection/additional
malloc

英特尔汇编语法与gcc内联asm是,嗯,不是很好;特别是,指定输入/输出操作数并不容易。我认为要使用
pthread\u getspecific
机制实现这一点,您需要将代码更改为:

__asm__("pushad\n\t"
    "push tsd_key\n\t"               <---- threadspecific data key (arg to call)
    "call pthread_getspecific\n\t"   <---- gets "str" as per above
    "add esp, 4\n\t"                 <---- get rid of the func argument
    "mov edi, [eax]\n\t"             <---- first ptr == "plainText"
    "mov ebx, [eax + 4]\n\t"         <---- 2nd ptr == "charsetTable"
    ...
\uuuuuasm\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

“按tsd\U键\n\t”如果两个或多个线程可以访问您的
纯文本
可设置字符
变量,您需要锁定对这些变量的访问。从您发布的内容很难判断这是否真的是问题。您能给我们看一下线程代码吗?您应该将您的
asm
声明为
volatile
作为其他变量ise GCC可能会移动它。此外,在clobberlist中应该有
内存
。请参阅。尽量避免使用全局变量。在这种情况下,简单的方法是使用堆栈变量。另一种更复杂的可能性是使用线程局部变量。顺便说一句,asm代码很慢。特别是
xlat
指令(这可能是20年前最快的方法)应该避免。我考虑过。现在我试过了。它似乎起作用了。但我想这意味着速度大大降低。我必须先锁定
明文
,然后在释放锁之前复制内容,并对明文进行哈希运算。但似乎别无选择。谢谢:)这看起来很有希望。我一定会尝试。谢谢你的精彩和详细的帖子。谢谢!我把它标记为我的解决方案,因为这是对我问题的直接回答,我去掉了全局变量。速度测量显示,它甚至快了一点。再次感谢。是的,它可能更快,因为它是“无数据共享”的情况(每个线程复制一次变量);更高的内存占用比更好的并行性。
static pthread_key_y tsd_key;
(void)pthread_key_create(&tsd_key);    /* unlikely to fail; handle if you want */
struct { char *plainText, char *charsetTable } *str =
    pthread_getspecific(tsd_key);

if (str == NULL) {
    str = malloc(2 * sizeof(char *));
    str.plainText = malloc(size_of_plaintext);
    str.charsetTable = malloc(size_of_charsetTable);
    initialize(str.plainText);          /* put the data for this thread in */
    initialize(str.charsetTable);       /* ditto */
    pthread_setspecific(tsd_key, str);
}
char *plaintext = str.plainText;
char *charsetTable = str.charsetTable;
__asm__("pushad\n\t"
    "push tsd_key\n\t"               <---- threadspecific data key (arg to call)
    "call pthread_getspecific\n\t"   <---- gets "str" as per above
    "add esp, 4\n\t"                 <---- get rid of the func argument
    "mov edi, [eax]\n\t"             <---- first ptr == "plainText"
    "mov ebx, [eax + 4]\n\t"         <---- 2nd ptr == "charsetTable"
    ...