-
Notifications
You must be signed in to change notification settings - Fork 7
/
coda.h
263 lines (228 loc) · 6.27 KB
/
coda.h
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
//writer [email protected]
#ifndef __CODA_H__
#define __CODA_H__
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <link.h>
#include <sys/procfs.h>
#include <string>
#include <vector>
#include <iomanip>
#include <typeinfo>
#include <regex.h>
#include "coda_utils.h"
#define offset_of(TYPE,mem) (unsigned long)(&((TYPE*)0)->mem)
#define LIB_NAME_LEN 2048
#define CURRENT_THREAD 0xffffffff
enum RetCode {
SUCCESS = 0,
PART_SUCCESS = 1,
FALIURE = -1
};
extern bool coda_debug;
class CoreObject {
public: // structs
struct ObjectEntry {
std::string access;
std::string filename;
ElfW(Phdr) *phdr;
uint64_t symtab;
uint64_t strtab;
//Assuming gnu hash table
uint64_t hashtab;
uint64_t strtab_size;
uint64_t base_addr;
uint32_t sym_count;
bool symtab_loaded;
bool cant_load_symtab;
};
struct ProcessContext {
elf_prpsinfo *m_prinfo;
std::vector<elf_prstatus*> m_vprst;
};
public: // methods
static CoreObject& GetCoreObject(char const *cfname = 0);
ObjectEntry* FindObjectEntry(uint64_t va, bool filesz = true);
RetCode Addr2Name(uint64_t va, std::string &symname);
void ShowMemoryMap();
void ShowThrList();
void ShowBT(bool regs = false);
void ShowBTAll();
void ShowIfMinidump();
void SwitchToThread(size_t thrno = CURRENT_THREAD);
int ShowStrings(char *regex);
void EnableDemangle() {m_demangle = true;}
void DisableDemangle() {m_demangle = false;}
bool IsMiniDump() {return m_mini_dump;}
void Switch2InteractiveMode();
template <typename T>
T GetValueAtVA(uint64_t va);
template <typename T>
T* GetValueAtVA(uint64_t va, size_t units);
template <typename T>
void ShowValueAtVA(uint64_t va, size_t units = 1);
bool ElfHdr(ElfW(Ehdr) &ehdr)
{
return (ELFMAG0 == ehdr.e_ident[EI_MAG0]) &&
(ELFMAG1 == ehdr.e_ident[EI_MAG1]) &&
(ELFMAG2 == ehdr.e_ident[EI_MAG2]) &&
(ELFMAG3 == ehdr.e_ident[EI_MAG3]);
}
ElfW(Ehdr) CoreHdr() {return m_core_ehdr;}
void ShowDisassembly(uint64_t va);
bool IsInteractiveMode() {return m_interactive_mode;}
private: // methods
CoreObject(char const *cfname);
CoreObject(CoreObject const &);
CoreObject const & operator=(CoreObject const &);
~CoreObject(){}
void CheckArch()
{
if ( EM_X86_64 != m_core_ehdr.e_machine )
{
std::cerr << "Architecture not recognized!\n";
exit(1);
}
}
void IsCoreFile()
{
if ( ET_CORE != m_core_ehdr.e_type )
{
std::cerr << "Not a CORE file!\n";
exit(1);
}
}
int CorePhdrNum() {return m_core_phdr_num;}
void Check4PN_XNUM();
void ExtractPhdrs();
void ExtractProcessVitals();
void ExtractSharedLibraries();
uint64_t ExtractDT_DEBUG(uint64_t ba, uint64_t va);
void AccessSharedLibsNames(uint64_t va);
void SetSegmentName(uint64_t va, uint64_t bva, const char *libname);
RetCode FindSymbol(ObjectEntry *oe, uint64_t va, std::string &symname);
void PrintBT(const user_regs_struct *urs);
void WelcomeMessage();
void Process_NT_FILE_Note();
void SetOrModifySegmentName(uint64_t va, const char *segname);
int ExtractStringsFromCoredump(regex_t *reg);
private: // structs
struct nt_file_element {
unsigned long start;
unsigned long end;
unsigned long pgoff;
};
private: //data members
File m_corefile;
ElfW(Ehdr) m_core_ehdr;
std::vector<ObjectEntry*> m_object_map;
ProcessContext m_pr_ctx;
ElfW(Phdr) *m_note_phdr;
uint64_t m_aux_phdr_va;
char *m_progname;
char *m_commandline;
char *m_nt_file_sec;
unsigned m_current_thread;
int m_core_phdr_num;
bool m_pthreads;
bool m_mini_dump;
bool m_demangle;
bool m_interactive_mode;
bool m_found_nt_file;
};
template <typename T>
T CoreObject::GetValueAtVA(uint64_t va)
{
ObjectEntry *oe = FindObjectEntry(va);
if (!oe)
throw std::runtime_error("Cant access VA");
if ((va + sizeof(T)) >=
(oe->phdr->p_vaddr + oe->phdr->p_filesz))
throw std::runtime_error("Invalid access");
off_t off = oe->phdr->p_offset + (va - oe->phdr->p_vaddr);
T value;
m_corefile >> File::Offset(off) >> value;
return value;
}
template <typename T>
T* CoreObject::GetValueAtVA(uint64_t va, size_t units)
{
ObjectEntry *oe = FindObjectEntry(va);
if (!oe)
throw std::runtime_error("Cant access VA");
if ((va + sizeof(T) * units) >=
(oe->phdr->p_vaddr + oe->phdr->p_filesz))
throw std::runtime_error("Invalid access");
off_t off = oe->phdr->p_offset + (va - oe->phdr->p_vaddr);
T* value;
value = new T[units];
m_corefile >> File::Offset(off) >> File::Units(units) >> value;
return value;
}
inline void UIntPrint(void *arg)
{
unsigned UI = *(unsigned*)arg;
std::cout << std::dec << UI;
}
inline void ULongPrint(void *arg)
{
unsigned long UL = *(unsigned long*)arg;
std::cout << std::dec << UL;
}
inline void LongPrint(void *arg)
{
long L = *(long*)arg;
std::cout << std::dec << L;
}
inline void IntPrint(void *arg)
{
int I = *(int*)arg;
std::cout << std::dec << I;
}
inline void AddrPrint(void *arg)
{
uint64_t Addr = *(uint64_t*)arg;
std::cout << "0x" << std::hex << Addr;
}
inline void CharPrint(void *arg)
{
unsigned char Ch = *(unsigned char*)arg;
std::cout << "'" << Ch << "' 0x" << std::hex << (int)Ch;
}
template <typename T>
void CoreObject::ShowValueAtVA(uint64_t va,size_t units)
{
T *pobj;
try {
pobj = GetValueAtVA<T>(va,units);
}
catch (std::runtime_error &eObj)
{
std::cout << eObj.what() << std::endl;
return;
}
void (*TypePrint)(void*);
if(typeid(T) == typeid(unsigned char))
TypePrint = CharPrint;
else if(typeid(T) == typeid(uint64_t))
TypePrint = AddrPrint;
else if(typeid(T) == typeid(long))
TypePrint = LongPrint;
else if(typeid(T) == typeid(int))
TypePrint = IntPrint;
else if(typeid(T) == typeid(unsigned long))
TypePrint = ULongPrint;
else if(typeid(T) == typeid(unsigned int))
TypePrint = UIntPrint;
for(size_t count = 0; count < units; ++count)
{
if(count != 0)
std::cout << ", ";
TypePrint(&pobj[count]);
}
std::cout << std::endl;
delete [] pobj;
}
#endif