Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Z
zipr_unpin_plugin
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
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
Open Source Software
zipr_unpin_plugin
Commits
ad61b42e
Commit
ad61b42e
authored
9 years ago
by
jdh8d
Browse files
Options
Downloads
Patches
Plain Diff
No commit message
No commit message
parent
d7695261
No related branches found
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
.gitattributes
+0
-2
0 additions, 2 deletions
.gitattributes
push64_relocs.cpp
+0
-368
0 additions, 368 deletions
push64_relocs.cpp
push64_relocs.h
+0
-127
0 additions, 127 deletions
push64_relocs.h
unpin.cpp
+10
-3
10 additions, 3 deletions
unpin.cpp
with
10 additions
and
500 deletions
.gitattributes
+
0
−
2
View file @
ad61b42e
...
...
@@ -3,7 +3,5 @@
/SConstruct -text
/configure.in -text
/install-sh -text
/push64_relocs.cpp -text
/push64_relocs.h -text
/unpin.cpp -text
/unpin.h -text
This diff is collapsed.
Click to expand it.
push64_relocs.cpp
deleted
100644 → 0
+
0
−
368
View file @
d7695261
/***************************************************************************
* Copyright (c) 2014 Zephyr Software LLC. All rights reserved.
*
* This software is furnished under a license and/or other restrictive
* terms and may be used and copied only in accordance with such terms
* and the inclusion of the above copyright notice. This software or
* any other copies thereof may not be provided or otherwise made
* available to any other person without the express written consent
* of an authorized representative of Zephyr Software LCC. Title to,
* ownership of, and all rights in the software is retained by
* Zephyr Software LCC.
*
* Zephyr Software LLC. Proprietary Information
*
* Unless otherwise specified, the information contained in this
* directory, following this legend, and/or referenced herein is
* Zephyr Software LLC. (Zephyr) Proprietary Information.
*
* CONTACT
*
* For technical assistance, contact Zephyr Software LCC. at:
*
*
* Zephyr Software, LLC
* 2040 Tremont Rd
* Charlottesville, VA 22911
*
* E-mail: jwd@zephyr-software.com
**************************************************************************/
#include
<zipr_sdk.h>
#include
<string>
#include
<algorithm>
#include
"utils.hpp"
#include
"Rewrite_Utility.hpp"
#include
"push64_relocs.h"
using
namespace
libIRDB
;
using
namespace
std
;
using
namespace
Zipr_SDK
;
using
namespace
ELFIO
;
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
;
}
Push64Relocs_t
::
Push64Relocs_t
(
MemorySpace_t
*
p_ms
,
elfio
*
p_elfio
,
FileIR_t
*
p_firp
,
InstructionLocationMap_t
*
p_fil
)
:
m_memory_space
(
*
p_ms
),
m_elfio
(
*
p_elfio
),
m_firp
(
*
p_firp
),
final_insn_locations
(
*
p_fil
),
m_verbose
(
"verbose"
)
{
}
ZiprOptionsNamespace_t
*
Push64Relocs_t
::
RegisterOptions
(
ZiprOptionsNamespace_t
*
global
)
{
global
->
AddOption
(
&
m_verbose
);
return
NULL
;
}
bool
Push64Relocs_t
::
IsRelocationWithType
(
Relocation_t
*
reloc
,
std
::
string
type
)
{
return
(
reloc
->
GetType
().
find
(
type
)
!=
std
::
string
::
npos
);
}
// would be nice to have a FindRelocation function that takes a parameterized type.
Relocation_t
*
Push64Relocs_t
::
FindRelocationWithType
(
Instruction_t
*
insn
,
std
::
string
type
)
{
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
(
IsRelocationWithType
(
reloc
,
type
))
return
reloc
;
}
return
NULL
;
}
#define PUSH_DATA_BITS_MAX_LEN 16
void
Push64Relocs_t
::
HandlePush64Relocation
(
Instruction_t
*
insn
,
Relocation_t
*
reloc
)
{
Instruction_t
*
add_insn
=
new
Instruction_t
;
AddressID_t
*
add_addr
=
new
AddressID_t
;
Instruction_t
*
push_insn
=
NULL
,
*
jmp_insn
=
NULL
;
Relocation_t
*
add_reloc
=
new
Relocation_t
;
virtual_offset_t
push_addr
=
0
;
string
databits
=
""
;
uint8_t
push_data_bits
[
PUSH_DATA_BITS_MAX_LEN
]
=
{
0
,};
int
push_data_bits_len
=
0
;
plopped_relocs
.
insert
(
insn
);
push_insn
=
insn
;
jmp_insn
=
insn
->
GetFallthrough
();
assert
(
jmp_insn
);
push_data_bits_len
=
push_insn
->
GetDataBits
().
length
();
assert
(
push_data_bits_len
<
PUSH_DATA_BITS_MAX_LEN
);
memcpy
(
push_data_bits
,
(
uint8_t
*
)
push_insn
->
GetDataBits
().
c_str
(),
push_data_bits_len
);
/*
* Because we know that this is a push instruction,
* we know that the opcode is one byte.
* The pushed value will start at the 1th offset.
*/
push_addr
=
*
((
virtual_offset_t
*
)(
&
push_data_bits
[
1
]));
if
(
m_verbose
)
cout
<<
"push_addr: 0x"
<<
std
::
hex
<<
push_addr
<<
endl
;
assert
(
push_addr
!=
0
);
/*
* Step 0: Add the add instruction and its address.
*/
add_addr
->
SetFileID
(
push_insn
->
GetAddress
()
->
GetFileID
());
add_insn
->
SetAddress
(
add_addr
);
add_insn
->
SetFunction
(
push_insn
->
GetFunction
());
m_firp
.
GetAddresses
().
insert
(
add_addr
);
m_firp
.
GetInstructions
().
insert
(
add_insn
);
/*
* Step 1: Change the push to a call 0.
*/
// this is OK, but could we consider the insn->Assemble() method for readability?
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
->
SetFallthrough
(
NULL
);
insn
->
SetComment
(
push_insn
->
GetComment
()
+
" Thunk part"
);
/*
* Step 2: Create the add instruction.
*/
// this is OK, but could we consider the insn->Assemble() method for readability?
databits
=
""
;
databits
.
resize
(
8
);
databits
[
0
]
=
0x48
;
databits
[
1
]
=
0x81
;
databits
[
2
]
=
0x2c
;
databits
[
3
]
=
0x24
;
databits
[
4
]
=
0xff
;
databits
[
5
]
=
0xff
;
databits
[
6
]
=
0xff
;
databits
[
7
]
=
0xff
;
add_insn
->
SetDataBits
(
databits
);
/*
* Step 3: Put the relocation on the add instruction.
*/
add_reloc
->
SetOffset
(
push_addr
);
add_reloc
->
SetType
(
"add64"
);
add_insn
->
GetRelocations
().
insert
(
add_reloc
);
m_firp
.
GetRelocations
().
insert
(
add_reloc
);
if
(
m_verbose
)
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
()
{
int
push64_relocations_count
=
0
;
int
pcrel_relocations_count
=
0
;
// for each instruction
InstructionSet_t
::
iterator
iit
=
m_firp
.
GetInstructions
().
begin
();
for
(
iit
;
iit
!=
m_firp
.
GetInstructions
().
end
();
iit
++
)
{
Instruction_t
*
insn
=*
iit
;
Relocation_t
*
reloc
=
NULL
;
if
(
reloc
=
FindPushRelocation
(
insn
))
{
if
(
m_verbose
)
cout
<<
"Found a Push relocation:"
<<
insn
->
getDisassembly
()
<<
endl
;
HandlePush64Relocation
(
insn
,
reloc
);
push64_relocations_count
++
;
}
else
if
(
reloc
=
FindPcrelRelocation
(
insn
))
{
if
(
m_verbose
)
cout
<<
"Found a pcrel relocation."
<<
endl
;
plopped_relocs
.
insert
(
insn
);
pcrel_relocations_count
++
;
}
}
cout
<<
"#ATTRIBUTE push_relocations_count="
<<
std
::
dec
<<
push64_relocations_count
<<
endl
;
cout
<<
"#ATTRIBUTE pcrel_relocations_count="
<<
std
::
dec
<<
pcrel_relocations_count
<<
endl
;
}
void
Push64Relocs_t
::
UpdatePush64Adds
()
{
if
(
m_verbose
)
cout
<<
"UpdatePush64Adds()"
<<
endl
;
InstructionSet_t
::
iterator
insn_it
=
plopped_relocs
.
begin
();
for
(
insn_it
;
insn_it
!=
plopped_relocs
.
end
();
insn_it
++
)
{
Relocation_t
*
reloc
=
NULL
;
Instruction_t
*
insn
=
*
insn_it
;
if
(
reloc
=
FindPushRelocation
(
insn
))
{
// would consider updating this if statement to be a function call for simplicity/readability.
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
;
call
=
*
insn_it
;
add
=
call
->
GetTarget
();
assert
(
call
&&
add
);
call_addr
=
final_insn_locations
[
call
];
add_addr
=
final_insn_locations
[
add
];
if
(
call_addr
==
0
||
add_addr
==
0
)
{
if
(
m_verbose
)
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
();
// would this be simpler if we always used an add (or sub)
// and just signed the sign of the value we are adding (or subbing)?
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
+
2
,
(
const
char
*
)
&
add
,
1
);
}
m_memory_space
.
PlopBytes
(
add_addr
+
4
,
(
const
char
*
)
&
relocated_value
,
4
);
}
else
if
(
reloc
=
FindPcrelRelocation
(
insn
))
{
// would consider updating this if statement to be a function call for simplicity/readability.
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
;
#if 1
insn_addr
=
final_insn_locations
[
insn
];
if
(
insn_addr
==
0
)
{
if
(
m_verbose
)
cout
<<
"Skipping unplopped Pcrel relocation."
<<
endl
;
continue
;
}
assert
(
insn_addr
!=
0
);
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_verbose
)
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
);
#endif
}
}
}
extern
"C"
Zipr_SDK
::
ZiprPluginInterface_t
*
GetPluginInterface
(
Zipr_SDK
::
Zipr_t
*
zipr_object
)
{
Zipr_SDK
::
MemorySpace_t
*
p_ms
=
zipr_object
->
GetMemorySpace
();
ELFIO
::
elfio
*
p_elfio
=
zipr_object
->
GetELFIO
();
libIRDB
::
FileIR_t
*
p_firp
=
zipr_object
->
GetFileIR
();
Zipr_SDK
::
InstructionLocationMap_t
*
p_fil
=
zipr_object
->
GetLocationMap
();
return
new
Push64Relocs_t
(
p_ms
,
p_elfio
,
p_firp
,
p_fil
);
}
This diff is collapsed.
Click to expand it.
push64_relocs.h
deleted
100644 → 0
+
0
−
127
View file @
d7695261
/***************************************************************************
* Copyright (c) 2014 Zephyr Software LLC. All rights reserved.
*
* This software is furnished under a license and/or other restrictive
* terms and may be used and copied only in accordance with such terms
* and the inclusion of the above copyright notice. This software or
* any other copies thereof may not be provided or otherwise made
* available to any other person without the express written consent
* of an authorized representative of Zephyr Software LCC. Title to,
* ownership of, and all rights in the software is retained by
* Zephyr Software LCC.
*
* Zephyr Software LLC. Proprietary Information
*
* Unless otherwise specified, the information contained in this
* directory, following this legend, and/or referenced herein is
* Zephyr Software LLC. (Zephyr) Proprietary Information.
*
* CONTACT
*
* For technical assistance, contact Zephyr Software LCC. at:
*
*
* Zephyr Software, LLC
* 2040 Tremont Rd
* Charlottesville, VA 22911
*
* E-mail: jwd@zephyr-software.com
**************************************************************************/
#ifndef push_relocs_h
#define push_relocs_h
#include
<libIRDB-core.hpp>
class
Push64Relocs_t
:
public
Zipr_SDK
::
ZiprPluginInterface_t
{
public:
Push64Relocs_t
(
Zipr_SDK
::
MemorySpace_t
*
p_ms
,
ELFIO
::
elfio
*
p_elfio
,
libIRDB
::
FileIR_t
*
p_firp
,
Zipr_SDK
::
InstructionLocationMap_t
*
p_fil
);
virtual
void
PinningBegin
()
{
}
virtual
void
PinningEnd
()
{
cout
<<
"Push64Plugin: Ending pinning, applying push64 relocs."
<<
endl
;
HandlePush64Relocs
();
}
virtual
void
DollopBegin
()
{
}
virtual
void
DollopEnd
()
{
}
virtual
void
CallbackLinkingBegin
()
{
}
virtual
void
CallbackLinkingEnd
()
{
cout
<<
"Push64Plugin: CBLinkEnd, updating adds."
<<
endl
;
UpdatePush64Adds
();
}
virtual
Zipr_SDK
::
ZiprOptionsNamespace_t
*
RegisterOptions
(
Zipr_SDK
::
ZiprOptionsNamespace_t
*
);
private
:
// main workhorses
void
HandlePush64Relocs
();
void
UpdatePush64Adds
();
// subsidiary workhorses
void
HandlePush64Relocation
(
libIRDB
::
Instruction_t
*
insn
,
libIRDB
::
Relocation_t
*
reloc
);
// helpers
bool
IsPcrelRelocation
(
libIRDB
::
Relocation_t
*
reloc
)
{
return
IsRelocationWithType
(
reloc
,
"pcrel"
);
}
bool
IsAdd64Relocation
(
libIRDB
::
Relocation_t
*
reloc
)
{
return
IsRelocationWithType
(
reloc
,
"add64"
);
}
bool
IsPush64Relocation
(
libIRDB
::
Relocation_t
*
reloc
)
{
return
IsRelocationWithType
(
reloc
,
"push64"
);
}
bool
Is32BitRelocation
(
libIRDB
::
Relocation_t
*
reloc
)
{
return
IsRelocationWithType
(
reloc
,
"push64"
);
}
libIRDB
::
Relocation_t
*
FindPcrelRelocation
(
libIRDB
::
Instruction_t
*
insn
)
{
return
FindRelocationWithType
(
insn
,
"pcrel"
);
}
libIRDB
::
Relocation_t
*
FindAdd64Relocation
(
libIRDB
::
Instruction_t
*
insn
)
{
return
FindRelocationWithType
(
insn
,
"add64"
);
}
libIRDB
::
Relocation_t
*
FindPush64Relocation
(
libIRDB
::
Instruction_t
*
insn
)
{
return
FindRelocationWithType
(
insn
,
"push64"
);
}
libIRDB
::
Relocation_t
*
Find32BitRelocation
(
libIRDB
::
Instruction_t
*
insn
)
{
return
FindRelocationWithType
(
insn
,
"32-bit"
);
}
libIRDB
::
Relocation_t
*
FindPushRelocation
(
libIRDB
::
Instruction_t
*
insn
)
{
libIRDB
::
Relocation_t
*
reloc
=
NULL
;
if
(
reloc
=
FindPush64Relocation
(
insn
))
{
return
reloc
;
}
if
(
reloc
=
Find32BitRelocation
(
insn
))
{
return
reloc
;
}
return
NULL
;
}
bool
IsRelocationWithType
(
libIRDB
::
Relocation_t
*
reloc
,
std
::
string
type
);
libIRDB
::
Relocation_t
*
FindRelocationWithType
(
libIRDB
::
Instruction_t
*
insn
,
std
::
string
type
);
// references to input
Zipr_SDK
::
MemorySpace_t
&
m_memory_space
;
ELFIO
::
elfio
&
m_elfio
;
libIRDB
::
FileIR_t
&
m_firp
;
Zipr_SDK
::
InstructionLocationMap_t
&
final_insn_locations
;
// local data.
libIRDB
::
InstructionSet_t
plopped_relocs
;
Zipr_SDK
::
ZiprBooleanOption_t
m_verbose
;
};
#endif
This diff is collapsed.
Click to expand it.
unpin.cpp
+
10
−
3
View file @
ad61b42e
...
...
@@ -66,10 +66,17 @@ void Unpin_t::DoUnpin()
// getWRT returns an BaseObj, but this reloc type expects an instruction
// safe cast and check.
assert
(
insn
);
assert
(
insn
->
GetIndirectBranchTargetAddress
());
cout
<<
"Unpin::Found data_to_insn_ptr relocation for pinned insn at "
<<
hex
<<
insn
->
GetIndirectBranchTargetAddress
()
->
GetVirtualOffset
()
<<
endl
;
if
(
insn
->
GetIndirectBranchTargetAddress
())
{
cout
<<
"Unpin::Found data_to_insn_ptr relocation for pinned insn at "
<<
hex
<<
insn
->
GetIndirectBranchTargetAddress
()
->
GetVirtualOffset
()
<<
endl
;
}
else
{
cout
<<
"Unpin::Warn: unpin found non-IBTA to unpin. probably it's unpinned twice. continuing anyhow."
<<
endl
;
}
int
found
=
false
;
for
(
...
...
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