1- How can I place a BP (conditional) to break when the string 102 is
accessed (x64. I do not know which function is used to load the
string)?
First, it is necessary to find the right method used to load the string. The standard one is LoadString
but, as @0xC0000022L mentioned, there are other options. Check the imports from the PE
file and determine which one can be.
In my case, I found out it was LoadStringW
, from user32.dll
.
In x86
, you will normally place a BP with a condition on some stack value. In x64
this normally works differently (x64 calling convention):
By default, the x64 calling convention passes the first four arguments
to a function in registers. The registers used for these arguments
depend on the position and type of the argument. Remaining arguments
get pushed on the stack in right-to-left order. Integer valued
arguments in the leftmost four positions are passed in left-to-right
order in RCX, RDX, R8, and R9, respectively...
According to the documentation LoadStringW function:
int LoadStringW(
HINSTANCE hInstance,
UINT uID, // --> The identifier of the string to be loaded.
LPWSTR lpBuffer,
int cchBufferMax
);
Therefore, uID
will be loaded in EDX
. The right breakpoint for x64dbg is:
bp user32:LoadStringW;bpcnd user32:LoadStringW,EDX==66
Note: 102 is 66h
2- How could I detect this code in a disassembler such as Ghidra/IDA?
In Ghidra this is automatically managed. By looking into the Defined Strings
you can find the strings in the resources:
pu_Error_140312196 XREF[12]:
FUN_1400... (*) ,FUN_140...
140312196 05004500... p_unicode u"Error" Rsrc String ID 102
From here it is trivial to go to the references.