티스토리 뷰

history | grep

240613/ 불법 복제

LHOIKTN 2024. 6. 14. 02:54

 

ebook

동생이 ebook을 샀는데 자기 계정으로 보라고 하길래  어떻게 그냥 뽑아낼 방법은 없을까 좀 뒤져봤는데,  

epub 파일의  확장자를 zip 으로 바꾸면 

 

이런식으로 구성되있는 것을 확인할 수 있는데, OEBPS안에 들어가면 

 

 

 

ebook에 필요한 컨텐츠들이 들어 있는거 같고..

 

 

대충 살펴보면  TEXT 폴더에 들어가서 파일을 살펴보니 위와 같이 암호화 되어 있었다.  

 

 

META-INF 폴더에 들어가면 아래와 같이

 

encryption.xml 파일이 들어 있다.  파일명에서 딱  이 해결하면 ebook에 걸려 있는 DRM을 해제할 수 있을 것 같은. 느낌이 온다. 

 

확인해보면 AES 로 해당 파일이 암호화 되어 있다.   ds:KeyInfo 에 들어갈 key만 안다고 끝이 아니고   

 

이게  모드랑 초기화 벡터?였나 그것도 알아야 될텐데   그래도 혹시 모르니까 x64dbg에 플러그인 추가해서 좀 뒤져봤는데  스트레스만 받았다.

 

그냥 스샷찍어서 그런게 훨씬 효율적으로 작업하는 방향인듯 하다. 

 

아무튼 헛짓거리하다가 그냥 캡쳐-리사이즈-PDF병합 이런식으로 하기로 했다. 

 

일단 

ebook viewer 띄운 다음에 content의 사이즈를 확인했다.

import mouseEvents from "global-mouse-events";
mouseEvents.on("mousedown", (event) => {
  console.log(event); // { x: 2962, y: 483, button: 1 }
});

이렇게 ebook viewer에서 컨텐츠 포함된 부분의 좌표를 확인했다.  

 const topLeft = { x: 1165, y: 107, };
 const bottomRight = { x: 1914, y: 977 };

 

bottomRight 좌표를 클릭하면 다음페이지로 넘어가는 거를 확인했고,

 

 

다음 버튼을 누르면 viewer의 왼쪽에   >   이런 아이콘이 등장해서 마우스를 잠깐 아래로 내려줘야했다.

const hideIconPos = { x: 1914, y: 1008 };

 

 

robotjs  라이브러리 활용하여 마우스 이동이랑 클릭을 자동화하고,  

screenshot-desktop  라이브러리 활용하여 스크린샷을 찍었다.

 

import robot from "robotjs";
import screenshot from "screenshot-desktop";

const topLeft = { x: 1165, y: 107 };
const bottomRight = { x: 1914, y: 977 };

const TOTAL_PAGE = 293;

// 다음으로 넘기기 위치
const nextPos = bottomRight;
// > 아이콘 숨기기 위해 마우스가 이동해야할 위치
const hideIconPos = { x: 1905, y: 1008 };

(async () => {
  // 
  robot.moveMouse(hideIconPos.x, hideIconPos.y);
  let cnt = 0;
  while (cnt < TOTAL_PAGE) {
    const filename = cnt + ".png";
    // 사진찍고
    await screenshot({ filename: filename });
    // 다음 페이지로 넘기고
    robot.moveMouse(nextPos.x, nextPos.y);
    robot.mouseClick();
    // 로딩 기다렸다가
    await sleep(500);
    // 마우스 위치 아래로 내리기
    robot.moveMouse(hideIconPos.x, hideIconPos.y);
    cnt++;
  }
})();

function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, ms);
  });
}

 

 

이렇게 스크린샷 다 찍은 다음

 

 

이미지 자르고  여백 좀 추가해서 pdf로 만들어줬다.

import fs from "node:fs";
import path from "node:path";
import { PDFDocument } from "pdf-lib";
import sharp from "sharp";
const MARGIN = 40;
const TOP_MARGIN = 20;
const CROP = 20;
const pdfDoc = await PDFDocument.create();

const pngFiles = fs
  .readdirSync("./412")
  .filter((file) => file.endsWith(".png"));
pngFiles.sort((a, b) => +a.split(".")[0] - +b.split(".")[0]);

for (const filename of pngFiles) {
  const filePath = path.join("./412", filename);

  const { width, height } = await sharp(filePath).metadata();

  const image = await sharp(filePath)
    .extract({
      left: 1165,
      top: 107,
      width: 1914 - 1165,
      height: 977 - 107,
    })
    .toBuffer();

  const imageData = await pdfDoc.embedPng(image);
  const page = pdfDoc.addPage([
    imageData.width + 2 * MARGIN,
    imageData.height + 2 * MARGIN + TOP_MARGIN,
  ]);
  page.drawImage(imageData, {
    x: MARGIN,
    y: MARGIN + TOP_MARGIN,
    width: imageData.width,
    height: imageData.height,
  });
  console.log(filename);
}

const pdfData = await pdfDoc.save();
fs.writeFileSync("result.pdf", pdfData);

 

 

암튼 이렇게 ebook 불법 복제를 해봤다.

 

볼만한데 화질이 뛰어나지 않아서 불법 복제한 느낌이 너무 난다. 

나중에 OCR 활용해서 텍스트 뽑아낸 다음,  pdf에서 텍스트로 인식할 수 있게 만들어봐야겠다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90

'history | grep' 카테고리의 다른 글

240617/잠수  (0) 2024.06.19
240616/키위  (0) 2024.06.17
240612/cascadia  (0) 2024.06.13
240610/잡념  (0) 2024.06.11
240606/생신  (0) 2024.06.07
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
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
글 보관함