Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Z
Zipr Toolchain
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Open Source Software
Zipr Toolchain
Commits
e75243f6
Commit
e75243f6
authored
9 years ago
by
whh8b
Browse files
Options
Downloads
Patches
Plain Diff
Adding support for pcrel relocations.
parent
af243814
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
SConstruct
+1
-1
1 addition, 1 deletion
SConstruct
push64_relocs.cpp
+226
-56
226 additions, 56 deletions
push64_relocs.cpp
push64_relocs.h
+4
-4
4 additions, 4 deletions
push64_relocs.h
with
231 additions
and
61 deletions
SConstruct
+
1
−
1
View file @
e75243f6
...
...
@@ -28,7 +28,7 @@ else:
env
.
Append
(
CFLAGS
=
"
-O3
"
)
env
.
Append
(
CXXFLAGS
=
"
-O3
"
)
env
.
Append
(
LINKFLAGS
=
"
-O3
"
)
env
.
Append
(
CXXFLAGS
=
"
-std=c++0x
"
)
#
env.Append(CXXFLAGS=" -std=c++0x")
# set 32/64 bit build properly
#print "env[64bit]="+str(env['do_64bit_build'])
...
...
This diff is collapsed.
Click to expand it.
push64_relocs.cpp
+
226
−
56
View file @
e75243f6
...
...
@@ -37,6 +37,16 @@
#include
"push64_relocs.h"
bool
arg_has_relative
(
const
ARGTYPE
&
arg
)
{
/* if it's relative memory, watch out! */
if
(
arg
.
ArgType
&
MEMORY_TYPE
)
if
(
arg
.
ArgType
&
RELATIVE_
)
return
true
;
return
false
;
}
using
namespace
libIRDB
;
using
namespace
std
;
using
namespace
Zipr_SDK
;
...
...
@@ -91,11 +101,97 @@ Relocation_t* Push64Relocs_t::FindPush64Relocation(Instruction_t* insn)
}
return
NULL
;
}
bool
Push64Relocs_t
::
IsPcrelRelocation
(
Relocation_t
*
reloc
)
{
return
(
reloc
->
GetType
().
find
(
"pcrel"
)
!=
std
::
string
::
npos
);
}
Relocation_t
*
Push64Relocs_t
::
FindPcrelRelocation
(
Instruction_t
*
insn
)
{
Instruction_t
*
first_slow_path_insn
=
NULL
;
RelocationSet_t
::
iterator
rit
=
insn
->
GetRelocations
().
begin
();
for
(
rit
;
rit
!=
insn
->
GetRelocations
().
end
();
rit
++
)
{
Relocation_t
*
reloc
=*
rit
;
if
(
IsPcrelRelocation
(
reloc
))
return
reloc
;
}
return
NULL
;
}
void
Push64Relocs_t
::
HandlePush64Relocation
(
Instruction_t
*
insn
,
Relocation_t
*
reloc
)
{
std
::
unique_ptr
<
CallAddPair_t
>
reloc_pair
(
new
CallAddPair_t
(
insn
,
insn
->
GetTarget
()));
call_add_pairs
.
insert
(
std
::
move
(
reloc_pair
));
Instruction_t
*
add_insn
=
new
Instruction_t
;
AddressID_t
*
add_addr
=
new
AddressID_t
;
Instruction_t
*
jmp_insn
=
NULL
;
virtual_offset_t
next_addr
=
0
;
string
databits
=
""
;
Relocation_t
*
add_reloc
=
new
Relocation_t
;
plopped_relocs
.
insert
(
insn
);
jmp_insn
=
insn
->
GetFallthrough
();
assert
(
jmp_insn
);
next_addr
=
insn
->
GetAddress
()
->
GetVirtualOffset
()
+
insn
->
GetDataBits
().
length
();
/*
* Change the push64 to a call/add pair.
*/
/*
* Step 0: Add the add instruction and its address.
*/
add_addr
->
SetFileID
(
insn
->
GetAddress
()
->
GetFileID
());
add_insn
->
SetAddress
(
add_addr
);
add_insn
->
SetFunction
(
insn
->
GetFunction
());
m_firp
.
GetAddresses
().
insert
(
add_addr
);
m_firp
.
GetInstructions
().
insert
(
add_insn
);
/*
* Step 1: Change the push to a call 0.
*/
databits
.
resize
(
5
);
databits
[
0
]
=
0xe8
;
databits
[
1
]
=
0x00
;
databits
[
2
]
=
0x00
;
databits
[
3
]
=
0x00
;
databits
[
4
]
=
0x00
;
insn
->
SetDataBits
(
databits
);
insn
->
SetTarget
(
add_insn
);
// Comment
insn
->
SetComment
(
insn
->
GetComment
()
+
" Thunk part"
);
/*
* Step 2: Create the add instruction.
*/
databits
=
""
;
databits
.
resize
(
7
);
databits
[
0
]
=
0x81
;
databits
[
1
]
=
0x2c
;
databits
[
2
]
=
0x24
;
databits
[
3
]
=
0xff
;
databits
[
4
]
=
0xff
;
databits
[
5
]
=
0xff
;
databits
[
6
]
=
0xff
;
add_insn
->
SetDataBits
(
databits
);
/*
* Step 3: Put the relocation on the add instruction.
*/
add_reloc
->
SetOffset
(
next_addr
);
add_reloc
->
SetType
(
"add64"
);
add_insn
->
GetRelocations
().
insert
(
add_reloc
);
m_firp
.
GetRelocations
().
insert
(
add_reloc
);
if
(
m_opts
.
GetVerbose
())
cout
<<
"Adding an add/sub with reloc offset 0x"
<<
std
::
hex
<<
add_reloc
->
GetOffset
()
<<
endl
;
/*
* Step 4: Tell the add insn to fallthrough to the call.
*/
add_insn
->
SetFallthrough
(
jmp_insn
);
}
void
Push64Relocs_t
::
HandlePush64Relocs
()
...
...
@@ -107,15 +203,22 @@ void Push64Relocs_t::HandlePush64Relocs()
InstructionSet_t
::
iterator
iit
=
m_firp
.
GetInstructions
().
begin
();
for
(
iit
;
iit
!=
m_firp
.
GetInstructions
().
end
();
iit
++
)
{
Instruction_t
&
insn
=*
(
*
iit
)
;
Instruction_t
*
insn
=*
iit
;
insns
++
;
Relocation_t
*
reloc
=
FindPush64Relocation
(
&
insn
)
;
if
(
reloc
)
Relocation_t
*
reloc
=
NULL
;
if
(
reloc
=
FindPush64Relocation
(
insn
)
)
{
if
(
m_opts
.
GetVerbose
())
cout
<<
"Found a Push64 relocation."
<<
endl
;
HandlePush64Relocation
(
&
insn
,
reloc
);
HandlePush64Relocation
(
insn
,
reloc
);
handled
++
;
}
else
if
(
reloc
=
FindPcrelRelocation
(
insn
))
{
if
(
m_opts
.
GetVerbose
())
cout
<<
"Found a pcrel relocation."
<<
endl
;
plopped_relocs
.
insert
(
insn
);
handled
++
;
}
}
...
...
@@ -128,66 +231,133 @@ void Push64Relocs_t::UpdatePush64Adds()
{
if
(
m_opts
.
GetVerbose
())
cout
<<
"UpdatePush64Adds()"
<<
endl
;
CallAddPairs
_t
::
iterator
cap
_it
=
call_add_pair
s
.
begin
();
for
(
cap
_it
;
cap
_it
!=
call_add_pair
s
.
end
();
cap
_it
++
)
InstructionSet
_t
::
iterator
insn
_it
=
plopped_reloc
s
.
begin
();
for
(
insn
_it
;
insn
_it
!=
plopped_reloc
s
.
end
();
insn
_it
++
)
{
bool
change_to_add
=
false
;
RangeAddress_t
call_addr
=
0
;
RangeAddress_t
add_addr
=
0
;
int
add_offset
=
0
;
uint32_t
relocated_value
=
0
;
Instruction_t
*
call
=
NULL
,
*
add
=
NULL
;
CallAddPair_t
*
cap
=
cap_it
->
get
();
Relocation_t
*
add_reloc
=
NULL
;
call
=
cap
->
first
;
add
=
cap
->
second
;
call_addr
=
final_insn_locations
[
call
];
add_addr
=
final_insn_locations
[
add
];
if
(
call_addr
==
0
||
add_addr
==
0
)
Relocation_t
*
reloc
=
NULL
;
Instruction_t
*
insn
=
*
insn_it
;
if
(
reloc
=
FindPush64Relocation
(
insn
))
{
if
(
m_opts
.
GetVerbose
())
cout
<<
"Call/Add pair not plopped?"
<<
endl
;
continue
;
}
bool
change_to_add
=
false
;
RangeAddress_t
call_addr
=
0
;
RangeAddress_t
add_addr
=
0
;
int
add_offset
=
0
;
uint32_t
relocated_value
=
0
;
Instruction_t
*
call
=
NULL
,
*
add
=
NULL
;
Relocation_t
*
add_reloc
=
NULL
;
add_reloc
=
F
in
dAdd64Relocation
(
add
)
;
assert
(
add_reloc
&&
"Add in Call/Add pair must have relocation."
);
call
=
*
in
sn_it
;
add
=
call
->
GetTarget
(
);
add_offset
=
add_reloc
->
GetOffset
(
);
assert
(
call
&&
add
);
/*
* Stupid call will push the NEXT instruction address.
*/
call_addr
+=
call
->
GetDataBits
().
length
();
call_addr
=
final_insn_locations
[
call
];
add_addr
=
final_insn_locations
[
add
];
if
(
add_offset
>
call_addr
)
{
change_to_add
=
true
;
relocated_value
=
add_offset
-
call_addr
;
if
(
call_addr
==
0
||
add_addr
==
0
)
{
if
(
m_opts
.
GetVerbose
())
cout
<<
"Call/Add pair not plopped?"
<<
endl
;
continue
;
}
add_reloc
=
FindAdd64Relocation
(
add
);
assert
(
add_reloc
&&
"Add in Call/Add pair must have relocation."
);
add_offset
=
add_reloc
->
GetOffset
();
/*
* Stupid call will push the NEXT instruction address.
*/
call_addr
+=
call
->
GetDataBits
().
length
();
if
(
add_offset
>
call_addr
)
{
change_to_add
=
true
;
relocated_value
=
add_offset
-
call_addr
;
}
else
{
relocated_value
=
call_addr
-
add_offset
;
}
cout
<<
"Relocating a(n) "
<<
((
change_to_add
)
?
"add"
:
"sub"
)
<<
" from "
<<
std
::
hex
<<
call_addr
<<
" at "
<<
std
::
hex
<<
add_addr
<<
endl
<<
"Using 0x"
<<
std
::
hex
<<
relocated_value
<<
" as the updated offset."
<<
endl
<<
"Using 0x"
<<
std
::
hex
<<
add_offset
<<
" as the base offset."
<<
endl
;
if
(
change_to_add
)
{
char
add
=
(
char
)
0x04
;
m_memory_space
.
PlopBytes
(
add_addr
+
1
,
(
const
char
*
)
&
add
,
1
);
}
m_memory_space
.
PlopBytes
(
add_addr
+
3
,
(
const
char
*
)
&
relocated_value
,
4
);
}
else
else
if
(
reloc
=
FindPcrelRelocation
(
insn
))
{
relocated_value
=
call_addr
-
add_offset
;
}
uint8_t
memory_offset
=
0
;
int32_t
existing_offset
=
0
;
int32_t
new_offset
=
0
;
uint32_t
insn_addr
=
0
;
int
existing_offset_size
=
0
;
uint8_t
*
insn_bytes
=
NULL
;
int
insn_bytes_len
=
0
;
DISASM
d
;
ARGTYPE
*
arg
=
NULL
;
insn_addr
=
final_insn_locations
[
insn
];
if
(
insn_addr
==
0
)
{
if
(
m_opts
.
GetVerbose
())
cout
<<
"Skipping unplopped Pcrel relocation."
<<
endl
;
continue
;
}
assert
(
insn_addr
!=
0
);
cout
<<
"Relocating a(n) "
<<
((
change_to_add
)
?
"add"
:
"sub"
)
<<
" from "
<<
std
::
hex
<<
call_addr
<<
" at "
<<
std
::
hex
<<
add_addr
<<
endl
<<
"Using 0x"
<<
std
::
hex
<<
relocated_value
<<
" as the updated offset."
<<
endl
<<
"Using 0x"
<<
std
::
hex
<<
add_offset
<<
" as the base offset."
<<
endl
;
if
(
change_to_add
)
{
char
add
=
(
char
)
0x04
;
m_memory_space
.
PlopBytes
(
add_addr
+
1
,
(
const
char
*
)
&
add
,
1
);
insn_bytes_len
=
sizeof
(
uint8_t
)
*
insn
->
GetDataBits
().
length
();
insn_bytes
=
(
uint8_t
*
)
malloc
(
insn_bytes_len
);
memcpy
(
insn_bytes
,
insn
->
GetDataBits
().
c_str
(),
insn_bytes_len
);
insn
->
Disassemble
(
d
);
if
(
arg_has_relative
(
d
.
Argument1
))
arg
=&
d
.
Argument1
;
if
(
arg_has_relative
(
d
.
Argument2
))
arg
=&
d
.
Argument2
;
if
(
arg_has_relative
(
d
.
Argument3
))
arg
=&
d
.
Argument3
;
assert
(
arg
);
memory_offset
=
arg
->
Memory
.
DisplacementAddr
-
d
.
EIP
;
existing_offset_size
=
arg
->
Memory
.
DisplacementSize
;
assert
(
memory_offset
>=
0
&&
memory_offset
<=
15
&&
(
existing_offset_size
==
1
||
existing_offset_size
==
2
||
existing_offset_size
==
4
||
existing_offset_size
==
8
));
memcpy
((
uint8_t
*
)
&
existing_offset
,
(
uint8_t
*
)
&
insn_bytes
[
memory_offset
],
existing_offset_size
);
new_offset
=
existing_offset
-
insn_addr
;
if
(
m_opts
.
GetVerbose
())
cout
<<
"Relocating a pcrel relocation with 0x"
<<
std
::
hex
<<
existing_offset
<<
" existing offset at 0x"
<<
insn_addr
<<
"."
<<
endl
<<
"Based on: "
<<
d
.
CompleteInstr
<<
endl
<<
"New address: 0x"
<<
std
::
hex
<<
new_offset
<<
endl
;
m_memory_space
.
PlopBytes
(
insn_addr
+
memory_offset
,
(
const
char
*
)
&
new_offset
,
existing_offset_size
);
}
m_memory_space
.
PlopBytes
(
add_addr
+
3
,
(
const
char
*
)
&
relocated_value
,
4
);
}
}
...
...
This diff is collapsed.
Click to expand it.
push64_relocs.h
+
4
−
4
View file @
e75243f6
...
...
@@ -31,9 +31,7 @@
#ifndef nonce_relocs_h
#define nonce_relocs_h
typedef
std
::
pair
<
Instruction_t
*
,
Instruction_t
*>
CallAddPair_t
;
typedef
std
::
set
<
std
::
unique_ptr
<
CallAddPair_t
>>
CallAddPairs_t
;
typedef
std
::
set
<
Instruction_t
*>
InstructionPtrSet_t
;
class
Push64Relocs_t
:
public
Zipr_SDK
::
ZiprPluginInterface_t
{
public:
...
...
@@ -71,6 +69,8 @@ class Push64Relocs_t : public Zipr_SDK::ZiprPluginInterface_t
void
UpdatePush64Adds
();
// helpers
bool
IsPcrelRelocation
(
libIRDB
::
Relocation_t
*
reloc
);
libIRDB
::
Relocation_t
*
FindPcrelRelocation
(
libIRDB
::
Instruction_t
*
insn
);
bool
IsAdd64Relocation
(
libIRDB
::
Relocation_t
*
reloc
);
libIRDB
::
Relocation_t
*
FindAdd64Relocation
(
libIRDB
::
Instruction_t
*
insn
);
bool
IsPush64Relocation
(
libIRDB
::
Relocation_t
*
reloc
);
...
...
@@ -85,7 +85,7 @@ class Push64Relocs_t : public Zipr_SDK::ZiprPluginInterface_t
Zipr_SDK
::
InstructionLocationMap_t
&
final_insn_locations
;
// local data.
CallAddPairs_t
call_add_pair
s
;
InstructionPtrSet_t
plopped_reloc
s
;
};
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment