挂钩 sleep 和 beep 系统调用

逆向工程 函数挂钩 系统调用 葡萄酒
2021-06-14 12:00:09

我有一个二进制文件,它使用对 Beep & Sleep 的调用播放莫尔斯电码。

这个文件是 Windows PE32 exe,我在我的 Ubuntu (16.04) 上通过 Wine 打开它。

如何提取在调用时传递给 Sleep 或 Beep 的参数?

理想的结果是从终端打开文件,每次调用 Sleep 时它都会记录

  • 睡眠(毫秒
  • 蜂鸣声(频率持续时间

二进制文件已打包和混淆,我可以编辑 Kernel32.dll 并扩展这些方法吗?

  • 我可以使用strace吗?如果是这样,我如何过滤 Sleep & Beep ?
2个回答

不知道你的意思
dot 总是听起来像 dot 不是吗?所以从逻辑上讲,它总是具有相同的频率和相同的持续时间?

像明智的破折号总是听起来像破折号?
如果它每次听起来都像monkeydash , goatdash , pigdash 那样变化,那么它就不会是莫尔斯电码……
所以从逻辑上讲,dash 将具有相同的频率和持续时间

所以合乎逻辑的结论是,如果你在特定程序中永远记录它们后就记录它们

法师有意义吗?

现在撇开为什么你需要编辑系统dll?你不能运行调试器并在二进制文件上设置断点吗?为什么 ?
是不是因为它被打包和混淆,并且有大量的反调试措施,包括检查系统 dll 上的断点?

如果是这样你可以尝试一些像frida这样的东西

假设你有一些这样的代码

#include <windows.h>
#include <stdio.h>
void beepchar(char letter) {
    char *beeps[] = { 
        ".-","-...","-.-.","-..",".","..-.","--.","....","..",
        ".---","-.-",".-..","--",        "-.","---",".--.","--.-",
        ".-.","...","-","..-","...-",".--","-..-","-.--","--.."
    };
    char *curbeep= (beeps[(letter -'a')]);
    printf("%s " , curbeep);
    while(*curbeep) {
        if( *curbeep == '.') {
            printf ("dot "); Beep(440,200);
        } else {
            printf("dash "); Beep(440,400);
        } curbeep++;
    }printf("\n");
}
int main (int argc , char* argv[]) {
    if(argc !=2) {
        printf ("usage %s some string\n",argv[0]);
        exit(0);
    } char *letter = argv[1];
    while(*letter) {
        unsigned char temp = *(unsigned char *)letter;
        if(isalpha(temp))        {
            beepchar((char)tolower(temp));
        } else {
            printf("not an alphabet\n");
        } letter++;
    } return 0;
}

编译和执行时,你应该得到这样的输出和声音

:\>morsebeeper.exe
usage morsebeeper.exe some string
:\>morsebeeper.exe "Hello World"
.... dot dot dot dot
. dot
.-.. dot dash dot dot
.-.. dot dash dot dot
--- dash dash dash
not an alphabet
.-- dot dash dash
--- dash dash dash
.-. dot dash dot
.-.. dot dash dot dot
-.. dash dot dot

:\>

您可以使用 frida-trace 来记录哔哔声

只需运行frida-trace -i "Beep" .\yourexe

并根据需要动态编辑自动生成的处理程序并重新加载它

:\>frida-trace -i "Beep" .\morsebeeper.exe Hello
Instrumenting functions...
Beep: Loaded handler at "xxx\__handlers__\kernel32.dll\Beep.js"
Beep: Loaded handler at "xxx\__handlers__\KERNELBASE.dll\Beep.js"
Started tracing 2 functions. Press Ctrl+C to stop.
           /* TID 0xf44 */
   109 ms  Beep()
   110 ms     | Beep(440 , 200) << dot
   314 ms  Beep()
   315 ms     | Beep(440 , 200) << dot
   547 ms  Beep()
   547 ms     | Beep(440 , 200) << dot
   800 ms  Beep()
   800 ms     | Beep(440 , 200) << dot   
   four dots above = h          <<<<<<<<<<<<<<<<
  1093 ms  Beep()
  1094 ms     | Beep(440 , 200) << dot
  one dot above is e            <<<<<<<<<<<<<<<<<<

  l
  1382 ms  Beep()
  1382 ms     | Beep(440 , 200) << dot
  1609 ms  Beep()
  1609 ms     | Beep(440 , 400) << dash
  2104 ms  Beep()
  2104 ms     | Beep(440 , 200)
  2333 ms  Beep()
  2333 ms     | Beep(440 , 200)
  l
  2614 ms  Beep()
  2614 ms     | Beep(440 , 200)
  2895 ms  Beep()
  2896 ms     | Beep(440 , 400)
  3301 ms  Beep()
  3302 ms     | Beep(440 , 200)
  3503 ms  Beep()
  3503 ms     | Beep(440 , 200)
  o
  3705 ms  Beep()
  3705 ms     | Beep(440 , 400)
  4197 ms  Beep()
  4198 ms     | Beep(440 , 400)
  4604 ms  Beep()
  4604 ms     | Beep(440 , 400)
stdout> .... dot dot dot dot
stdout> . dot
stdout> .-.. dot dash dot dot
stdout> .-.. dot dash dot dot
stdout> --- dash dash dash
stdout>
stderr>
Process terminated

:\>

如果您使用的是 Wine,则只需要启用跟踪。请执行下列操作:

$ WINEDEBUG="trace+msvcrt" wine your_binary.exe

查看 Wine 的源代码,我确认 Sleep 和 Beep 都被跟踪。

:

void CDECL MSVCRT__beep( unsigned int freq, unsigned int duration)
{
    TRACE(":Freq %d, Duration %d\n",freq,duration);
    Beep(freq, duration);
}

睡眠

void CDECL MSVCRT__sleep(MSVCRT_ulong timeout)
{
  TRACE("_sleep for %d milliseconds\n",timeout);
  Sleep((timeout)?timeout:1);
}

自然,您将需要过滤掉许多其他消息。只需执行“grep -v”就足够了。