mirror of
https://github.com/tiann/KernelSU.git
synced 2025-02-20 11:43:32 +08:00
Add ci for manager and userspace (#2)
* kernel: move EXPECTED_* macro to Makefile * manager: add sign configs * tools: add check_v2 * CI: build manager * CI: build userspace
This commit is contained in:
parent
6b84b7ed4d
commit
8e89b90b80
40
.github/workflows/build-manager.yml
vendored
Normal file
40
.github/workflows/build-manager.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
name: Build Manager
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./manager
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: set up JDK 11
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'temurin'
|
||||
cache: gradle
|
||||
- name: Extract keystore
|
||||
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/main' ) || github.ref_type == 'tag' }}
|
||||
run: |
|
||||
if [ ! -z "${{ secrets.KEY_STORE }}" ]; then
|
||||
echo KEYSTORE_PASSWORD='${{ secrets.KEYSTORE_PASSWORD }}' >> sign.properties
|
||||
echo KEY_ALIAS='${{ secrets.KEY_ALIAS }}' >> sign.properties
|
||||
echo KEY_PASSWORD='${{ secrets.KEY_PASSWORD }}' >> sign.properties
|
||||
echo KEYSTORE_FILE='../key.jks' >> sign.properties
|
||||
echo ${{ secrets.KEYSTORE }} | base64 --decode > key.jks
|
||||
fi
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: manager
|
||||
path: manager/app/build/outputs/apk/release/*.apk
|
||||
|
24
.github/workflows/build-userspace.yml
vendored
Normal file
24
.github/workflows/build-userspace.yml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
name: Build Userspace
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: nttld/setup-ndk@v1
|
||||
with:
|
||||
ndk-version: r25b
|
||||
local-cache: true
|
||||
- name: Build with NDK
|
||||
working-directory: ./userspace
|
||||
run: ndk-build
|
||||
- name: Upload a Build Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: su
|
||||
path: ./userspace/libs
|
||||
|
@ -6,4 +6,8 @@ obj-y += sucompat.o
|
||||
|
||||
obj-y += selinux/
|
||||
|
||||
EXPECTED_SIZE := 0x033b
|
||||
EXPECTED_HASH := 0xb0b91415
|
||||
ccflags-y += -DEXPECTED_SIZE=$(EXPECTED_SIZE)
|
||||
ccflags-y += -DEXPECTED_HASH=$(EXPECTED_HASH)
|
||||
ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat
|
||||
|
@ -112,9 +112,6 @@ clean:
|
||||
return sign;
|
||||
}
|
||||
|
||||
#define EXPECTED_SIZE 0x033b
|
||||
#define EXPECTED_HASH 0xb0b91415
|
||||
|
||||
int is_manager_apk(char* path) {
|
||||
return check_v2_signature(path, EXPECTED_SIZE, EXPECTED_HASH);
|
||||
}
|
2
manager/.gitignore
vendored
2
manager/.gitignore
vendored
@ -13,3 +13,5 @@
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
sign.properties
|
||||
key.jks
|
||||
|
@ -7,6 +7,10 @@ android {
|
||||
namespace 'me.weishu.kernelsu'
|
||||
compileSdk 33
|
||||
|
||||
signingConfigs {
|
||||
sign
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "me.weishu.kernelsu"
|
||||
minSdk 26
|
||||
@ -29,6 +33,7 @@ android {
|
||||
release {
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.sign
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
@ -83,4 +88,6 @@ dependencies {
|
||||
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
|
||||
debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
|
||||
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply from: rootProject.file('sign.gradle')
|
4
manager/sign.example.properties
Normal file
4
manager/sign.example.properties
Normal file
@ -0,0 +1,4 @@
|
||||
KEYSTORE_FILE=
|
||||
KEYSTORE_PASSWORD=
|
||||
KEY_ALIAS=
|
||||
KEY_PASSWORD=
|
16
manager/sign.gradle
Normal file
16
manager/sign.gradle
Normal file
@ -0,0 +1,16 @@
|
||||
def ksFile = rootProject.file('sign.properties')
|
||||
def props = new Properties()
|
||||
if (ksFile.canRead()) {
|
||||
props.load(new FileInputStream(ksFile))
|
||||
if (props != null) {
|
||||
android.signingConfigs.sign.storeFile file(props['KEYSTORE_FILE'])
|
||||
android.signingConfigs.sign.storePassword props['KEYSTORE_PASSWORD']
|
||||
android.signingConfigs.sign.keyAlias props['KEY_ALIAS']
|
||||
android.signingConfigs.sign.keyPassword props['KEY_PASSWORD']
|
||||
}
|
||||
} else {
|
||||
android.signingConfigs.sign.storeFile = android.signingConfigs.debug.storeFile
|
||||
android.signingConfigs.sign.storePassword = android.signingConfigs.debug.storePassword
|
||||
android.signingConfigs.sign.keyAlias = android.signingConfigs.debug.keyAlias
|
||||
android.signingConfigs.sign.keyPassword = android.signingConfigs.debug.keyPassword
|
||||
}
|
173
tools/check_v2.c
Normal file
173
tools/check_v2.c
Normal file
@ -0,0 +1,173 @@
|
||||
//
|
||||
// Created by Thom on 2019/3/8.
|
||||
//
|
||||
|
||||
// Credits: https://github.com/brevent/genuine/blob/master/src/main/jni/apk-sign-v2.c
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MAIN
|
||||
|
||||
#ifdef MAIN
|
||||
#include <stdio.h>
|
||||
#else
|
||||
|
||||
#include "common.h"
|
||||
#include "openat.h"
|
||||
|
||||
#endif
|
||||
|
||||
static bool isApkSigBlock42(const char *buffer) {
|
||||
// APK Sig Block 42
|
||||
return *buffer == 'A'
|
||||
&& *++buffer == 'P'
|
||||
&& *++buffer == 'K'
|
||||
&& *++buffer == ' '
|
||||
&& *++buffer == 'S'
|
||||
&& *++buffer == 'i'
|
||||
&& *++buffer == 'g'
|
||||
&& *++buffer == ' '
|
||||
&& *++buffer == 'B'
|
||||
&& *++buffer == 'l'
|
||||
&& *++buffer == 'o'
|
||||
&& *++buffer == 'c'
|
||||
&& *++buffer == 'k'
|
||||
&& *++buffer == ' '
|
||||
&& *++buffer == '4'
|
||||
&& *++buffer == '2';
|
||||
}
|
||||
|
||||
int checkSignature(const char *path) {
|
||||
unsigned char buffer[0x11] = {0};
|
||||
uint32_t size4;
|
||||
uint64_t size8, size_of_block;
|
||||
|
||||
#ifdef DEBUG
|
||||
LOGI("check signature for %s", path);
|
||||
#endif
|
||||
|
||||
int sign = -1;
|
||||
int fd = (int) openat(AT_FDCWD, path, O_RDONLY);
|
||||
#ifdef DEBUG_OPENAT
|
||||
LOGI("openat %s returns %d", path, fd);
|
||||
#endif
|
||||
if (fd < 0) {
|
||||
return sign;
|
||||
}
|
||||
|
||||
sign = 1;
|
||||
// https://en.wikipedia.org/wiki/Zip_(file_format)#End_of_central_directory_record_(EOCD)
|
||||
for (int i = 0;; ++i) {
|
||||
unsigned short n;
|
||||
lseek(fd, -i - 2, SEEK_END);
|
||||
read(fd, &n, 2);
|
||||
if (n == i) {
|
||||
lseek(fd, -22, SEEK_CUR);
|
||||
read(fd, &size4, 4);
|
||||
if ((size4 ^ 0xcafebabeu) == 0xccfbf1eeu) {
|
||||
#ifdef MAIN
|
||||
if (i > 0) {
|
||||
printf("warning: comment length is %d\n", i);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 0xffff) {
|
||||
#ifdef MAIN
|
||||
printf("error: cannot find eocd\n");
|
||||
#endif
|
||||
goto clean;
|
||||
}
|
||||
}
|
||||
|
||||
lseek(fd, 12, SEEK_CUR);
|
||||
// offset
|
||||
read(fd, &size4, 0x4);
|
||||
lseek(fd, (off_t) (size4 - 0x18), SEEK_SET);
|
||||
|
||||
read(fd, &size8, 0x8);
|
||||
read(fd, buffer, 0x10);
|
||||
if (!isApkSigBlock42((char *) buffer)) {
|
||||
goto clean;
|
||||
}
|
||||
|
||||
lseek(fd, (off_t) (size4 - (size8 + 0x8)), SEEK_SET);
|
||||
read(fd, &size_of_block, 0x8);
|
||||
if (size_of_block != size8) {
|
||||
goto clean;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
uint32_t id;
|
||||
uint32_t offset;
|
||||
read(fd, &size8, 0x8); // sequence length
|
||||
if (size8 == size_of_block) {
|
||||
break;
|
||||
}
|
||||
read(fd, &id, 0x4); // id
|
||||
offset = 4;
|
||||
#ifdef MAIN
|
||||
// printf("id: 0x%08x\n", id);
|
||||
#endif
|
||||
if ((id ^ 0xdeadbeefu) == 0xafa439f5u || (id ^ 0xdeadbeefu) == 0x2efed62f) {
|
||||
read(fd, &size4, 0x4); // signer-sequence length
|
||||
read(fd, &size4, 0x4); // signer length
|
||||
read(fd, &size4, 0x4); // signed data length
|
||||
offset += 0x4 * 3;
|
||||
|
||||
read(fd, &size4, 0x4); // digests-sequence length
|
||||
lseek(fd, (off_t) (size4), SEEK_CUR);// skip digests
|
||||
offset += 0x4 + size4;
|
||||
|
||||
read(fd, &size4, 0x4); // certificates length
|
||||
read(fd, &size4, 0x4); // certificate length
|
||||
offset += 0x4 * 2;
|
||||
#ifdef MAIN
|
||||
int hash = 1;
|
||||
signed char c;
|
||||
for (unsigned i = 0; i < size4; ++i) {
|
||||
read(fd, &c, 0x1);
|
||||
hash = 31 * hash + c;
|
||||
}
|
||||
offset += size4;
|
||||
// printf(" size: 0x%04x, hash: 0x%08x\n", size4, ((unsigned) hash) ^ 0x14131211u);
|
||||
printf("0x%04x 0x%08x\n", size4, ((unsigned) hash) ^ 0x14131211u);
|
||||
#else
|
||||
#if defined(GENUINE_SIZE) && defined(GENUINE_HASH)
|
||||
if (size4 == GENUINE_SIZE) {
|
||||
int hash = 1;
|
||||
signed char c;
|
||||
for (unsigned i = 0; i < size4; ++i) {
|
||||
read(fd, &c, 0x1);
|
||||
hash = 31 * hash + c;
|
||||
}
|
||||
offset += size4;
|
||||
if ((((unsigned) hash) ^ 0x14131211u) == GENUINE_HASH) {
|
||||
sign = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
sign = 0;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
lseek(fd, (off_t) (size8 - offset), SEEK_CUR);
|
||||
}
|
||||
|
||||
clean:
|
||||
close(fd);
|
||||
|
||||
return sign;
|
||||
}
|
||||
|
||||
#ifdef MAIN
|
||||
int main(int argc, char **argv) {
|
||||
if (argc > 1) {
|
||||
checkSignature(argv[1]);
|
||||
}
|
||||
}
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user