Skip to content

Commit

Permalink
add yoga-bios-unlock code
Browse files Browse the repository at this point in the history
  • Loading branch information
esno committed Jan 5, 2021
1 parent ca60b02 commit 819eddf
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/yoga-bios-unlock
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
yoga-unlock:
${CC} -o ./yoga-bios-unlock ./src/yoga-bios-unlock.c -O2 -Wall

clean:
rm ./yoga-bios-unlock
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# yoga-bios-unlock

Based on FlyGoat's work to unlock the BIOS advanced menu documented [here](https://zhuanlan.zhihu.com/p/184982689)
I wrote that tool to unlock my yoga laptop without using a proprietary software which is only available for Windows.

I'd like to thank FlyGoat a lot for giving me the right direction on how to translate his guide into low-level functions
provided by glibc.

This tool will unlock the advanced menu in your Lenovo Yoga Slim 7 14ARE05.

## Disclaimer

This tool may eat your cat, burn your house or do anything else beside the expected task.
So use it at your own risk and be aware that you're playing around with your BIOS which may end in a bricked device.

> Since I am still waiting for the arrival of my Yoga laptop this is quiet untested!
## Usage

git clone https://github.com/esno/yoga-bios-unlock.git
cd ./yoga-bios-unlock
make

su -c ./yoga-bios-unlock
121 changes: 121 additions & 0 deletions src/yoga-bios-unlock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/io.h>
#include <sys/types.h>

#define __DMI_PATH "/sys/class/dmi/id"

#define __BIOS_VENDOR "LENOVO"
#define __BIOS_VERSION "DMCN32WW"

#define __BOARD_NAME "LNVNB161216"
#define __BOARD_VENDOR "LENOVO"
#define __BOARD_VERSION "SDK0J40709 WIN"

#define __CHASSIS_VERSION "Yoga Slim 7 14ARE05"

int check_dmi(const char *file, const char *value);
int is_yoga(void);
int read_sysfs(const char *file, char *buffer, int n);

int check_dmi(const char *file, const char *value) {
int l = 128;
char buffer[l];

memset(buffer, 0, 128);
if (read_sysfs(file, buffer, l) < 0) {
fprintf(stderr, "cannot read /sys/class/dmi/id/%s\n", file);
return -1;
}

if (strcmp(value, buffer) != 0) {
fprintf(stderr, "%s does not match (expected: %s / got: %s)\n", file, value, buffer);
return -1;
}

return 0;
}

int is_yoga(void) {
int rc = 0;

if (check_dmi("bios_vendor", __BIOS_VENDOR) < 0)
rc = -1;
if (check_dmi("bios_version", __BIOS_VERSION) < 0)
rc = -2;
if (check_dmi("board_name", __BOARD_NAME) < 0)
rc = -3;
if (check_dmi("board_vendor", __BOARD_VENDOR) < 0)
rc = -4;
if (check_dmi("board_version", __BOARD_VERSION) < 0)
rc = -5;
if (check_dmi("chassis_version", __CHASSIS_VERSION) < 0)
rc = -6;

return rc;
}

int read_sysfs(const char *file, char *buffer, int n) {
int l = strlen(__DMI_PATH) + strlen(file) + 2;
char filename[l];
FILE *fd;
int c;

memset(filename, 0, l);
snprintf(filename, l, "%s/%s", __DMI_PATH, file);
fd = fopen(filename, "r");
if (fd == NULL)
return -1;

if ((c = fread(buffer, 1, n, fd)) < 0) {
if (feof(fd) == 0) {
fclose(fd);
return -2;
}
}

buffer[c - 1] = '\0';
fclose(fd);
return 0;
}

int main(int argc, const char **argv) {
char ack;

if (is_yoga() < 0) {
fprintf(stderr, "wrong device, aborting!\n");
return EXIT_FAILURE;
}

if (geteuid() != 0) {
fprintf(stderr, "Requires root privileges!\n");
return EXIT_FAILURE;
}

fprintf(stdout, "WARNING: use at your own risk!\n");
fprintf(stdout, "Agree? (y/Y) ");
scanf("%1s", &ack);
if (ack != 'y' && ack != 'Y') {
fprintf(stdout, "nothing to do here\n");
return EXIT_SUCCESS;
}

if (iopl(3) < 0) {
fprintf(stderr, "Can't set I/O privilege level (%s)\n", strerror(errno));
return EXIT_FAILURE;
}

if (ioperm(0x72, 2, 1) < 0) {
fprintf(stderr, "Can't set I/O permission (%s)\n", strerror(errno));
return EXIT_FAILURE;
}

outb_p(0xf7, 0x72);
outb_p(0x77, 0x73);

return EXIT_SUCCESS;
}

0 comments on commit 819eddf

Please sign in to comment.