168 lines
4.9 KiB
Java
168 lines
4.9 KiB
Java
package com.getkeepsafe.relinker.elf;
|
|
|
|
import com.getkeepsafe.relinker.elf.Elf;
|
|
import java.io.Closeable;
|
|
import java.io.EOFException;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.ByteOrder;
|
|
import java.nio.channels.FileChannel;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
|
|
/* loaded from: classes.dex */
|
|
public class ElfParser implements Closeable, Elf {
|
|
private final FileChannel a;
|
|
|
|
public ElfParser(File file) throws FileNotFoundException {
|
|
if (file == null || !file.exists()) {
|
|
throw new IllegalArgumentException("File is null or does not exist");
|
|
}
|
|
this.a = new FileInputStream(file).getChannel();
|
|
}
|
|
|
|
public Elf.Header a() throws IOException {
|
|
this.a.position(0L);
|
|
ByteBuffer allocate = ByteBuffer.allocate(8);
|
|
allocate.order(ByteOrder.LITTLE_ENDIAN);
|
|
if (e(allocate, 0L) != 1179403647) {
|
|
throw new IllegalArgumentException("Invalid ELF Magic!");
|
|
}
|
|
short a = a(allocate, 4L);
|
|
boolean z = a(allocate, 5L) == 2;
|
|
if (a == 1) {
|
|
return new Elf32Header(z, this);
|
|
}
|
|
if (a == 2) {
|
|
return new Elf64Header(z, this);
|
|
}
|
|
throw new IllegalStateException("Invalid class type!");
|
|
}
|
|
|
|
public List<String> b() throws IOException {
|
|
long j;
|
|
this.a.position(0L);
|
|
ArrayList arrayList = new ArrayList();
|
|
Elf.Header a = a();
|
|
ByteBuffer allocate = ByteBuffer.allocate(8);
|
|
allocate.order(a.a ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
|
|
long j2 = a.e;
|
|
int i = 0;
|
|
if (j2 == 65535) {
|
|
j2 = a.a(0).a;
|
|
}
|
|
long j3 = 0;
|
|
while (true) {
|
|
if (j3 >= j2) {
|
|
j = 0;
|
|
break;
|
|
}
|
|
Elf.ProgramHeader a2 = a.a(j3);
|
|
if (a2.a == 2) {
|
|
j = a2.b;
|
|
break;
|
|
}
|
|
j3++;
|
|
}
|
|
if (j == 0) {
|
|
return Collections.unmodifiableList(arrayList);
|
|
}
|
|
ArrayList arrayList2 = new ArrayList();
|
|
long j4 = 0;
|
|
while (true) {
|
|
Elf.DynamicStructure a3 = a.a(j, i);
|
|
long j5 = j;
|
|
long j6 = a3.a;
|
|
if (j6 == 1) {
|
|
arrayList2.add(Long.valueOf(a3.b));
|
|
} else if (j6 == 5) {
|
|
j4 = a3.b;
|
|
}
|
|
i++;
|
|
if (a3.a == 0) {
|
|
break;
|
|
}
|
|
j = j5;
|
|
}
|
|
if (j4 == 0) {
|
|
throw new IllegalStateException("String table offset not found!");
|
|
}
|
|
long a4 = a(a, j2, j4);
|
|
Iterator it = arrayList2.iterator();
|
|
while (it.hasNext()) {
|
|
arrayList.add(d(allocate, ((Long) it.next()).longValue() + a4));
|
|
}
|
|
return arrayList;
|
|
}
|
|
|
|
protected long c(ByteBuffer byteBuffer, long j) throws IOException {
|
|
a(byteBuffer, j, 8);
|
|
return byteBuffer.getLong();
|
|
}
|
|
|
|
@Override // java.io.Closeable, java.lang.AutoCloseable
|
|
public void close() throws IOException {
|
|
this.a.close();
|
|
}
|
|
|
|
protected String d(ByteBuffer byteBuffer, long j) throws IOException {
|
|
StringBuilder sb = new StringBuilder();
|
|
while (true) {
|
|
long j2 = 1 + j;
|
|
short a = a(byteBuffer, j);
|
|
if (a == 0) {
|
|
return sb.toString();
|
|
}
|
|
sb.append((char) a);
|
|
j = j2;
|
|
}
|
|
}
|
|
|
|
protected long e(ByteBuffer byteBuffer, long j) throws IOException {
|
|
a(byteBuffer, j, 4);
|
|
return byteBuffer.getInt() & 4294967295L;
|
|
}
|
|
|
|
private long a(Elf.Header header, long j, long j2) throws IOException {
|
|
for (long j3 = 0; j3 < j; j3++) {
|
|
Elf.ProgramHeader a = header.a(j3);
|
|
if (a.a == 1) {
|
|
long j4 = a.c;
|
|
if (j4 <= j2 && j2 <= a.d + j4) {
|
|
return (j2 - j4) + a.b;
|
|
}
|
|
}
|
|
}
|
|
throw new IllegalStateException("Could not map vma to file offset!");
|
|
}
|
|
|
|
protected short a(ByteBuffer byteBuffer, long j) throws IOException {
|
|
a(byteBuffer, j, 1);
|
|
return (short) (byteBuffer.get() & 255);
|
|
}
|
|
|
|
protected void a(ByteBuffer byteBuffer, long j, int i) throws IOException {
|
|
byteBuffer.position(0);
|
|
byteBuffer.limit(i);
|
|
long j2 = 0;
|
|
while (j2 < i) {
|
|
int read = this.a.read(byteBuffer, j + j2);
|
|
if (read == -1) {
|
|
throw new EOFException();
|
|
}
|
|
j2 += read;
|
|
}
|
|
byteBuffer.position(0);
|
|
}
|
|
|
|
protected int b(ByteBuffer byteBuffer, long j) throws IOException {
|
|
a(byteBuffer, j, 2);
|
|
return byteBuffer.getShort() & 65535;
|
|
}
|
|
}
|