-
Notifications
You must be signed in to change notification settings - Fork 18
/
lax_fbc.cc
86 lines (63 loc) · 2.41 KB
/
lax_fbc.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/* This file is part of nvlax.
nvlax is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
THIS SOFTWARE IS PROVIDED 'AS-IS', WITHOUT ANY EXPRESS
OR IMPLIED WARRANTY. IN NO EVENT WILL THE AUTHORS BE HELD
LIABLE FOR ANY DAMAGES ARISING FROM THE USE OF THIS SOFTWARE. */
#include <iostream>
#include <LIEF/ELF.hpp>
#include <Zydis/Zydis.h>
#include <ppk_assert.h>
#include "common.h"
using namespace LIEF::ELF;
const char *app_name = "nvlax_fbc";
const char *lib_name = "libnvidia-fbc.so.XXX";
int
main (int argc,
char **argv)
{
std::string_view input, output;
if (!parse_args(argc, argv, input, output)) {
return EXIT_FAILURE;
}
auto bin = Parser::parse(input.data());
size_t offset;
{
auto s_rodata = bin->get_section(".rodata");
offset = s_rodata.virtual_address() + s_rodata.search("This hardware does not support NvFBC");
}
std::cout << "[+] libnvidia-fbc.so\n";
bool found = false;
{
ZydisDecoder decoder;
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64);
auto s_text = bin->get_section(".text");
auto v_text_content = s_text.content();
uint8_t *data = v_text_content.data();
size_t length = v_text_content.size();
// find the only x-ref to the string above
ZydisDecodedInstruction instr;
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, data, length, &instr))) {
if (instr.mnemonic == ZYDIS_MNEMONIC_LEA) {
size_t temp = s_text.virtual_address() +
(data - v_text_content.data() + instr.length) +
instr.operands[1].mem.disp.value;
if (temp == offset) {
found = true;
offset = s_text.virtual_address() + data - v_text_content.data();
break;
}
}
data += instr.length;
length -= instr.length;
}
}
PPK_ASSERT_ERROR(found);
// this makes both branches identical
bin->patch_address(offset, { 0x48, 0x83, 0xC4, 0x08, 0xC3 });
bin->write(output.data());
std::cout << "[+] patched successfully\n";
return EXIT_SUCCESS;
}