WINE을 이용한 ActiveX 플러그인 포팅 사례

octaphial의 이미지

별 것은 아니지만 쓸만한 결과물이 하나 나와서 소개하려고 합니다.

IssacWeb이라는 보안 접속 프로그램이 있는데, 이걸 저희 학교 정보 시스템에서 사용자 인증할 때에 사용합니다. 문제는 이게 ActiveX 플러그인으로 구현되어 있어서 그간 윈도와 IE가 없으면 접속이 불가능했습니다. 여러 달 걸려서 이것을 WINE을 이용해 사용 가능하도록 만들었는데, 그 과정을 조금 소개하려고 합니다. 저와 같은 작업을 생각하시는 분이 있다면 차후 참고가 되겠지요.

우선 정석에 해당하는 방법은 이렇습니다. 윈도가 ActiveX 플러그인과 소통하는 공식적인 방법은 대강 이렇습니다:

1. 해당 .dll/ocx는 regsvr32 명령으로 미리 WINE에 등록되어 있어야 합니다.
2. 그 플러그인의 CLSID를 알고 CoCreateInstance 함수로 Unknown 인터페이스를 얻습니다.
3. 그 인터페이스의 QueryInterface 함수로 Dispatch 인터페이스를 얻습니다.
4. Dispatch 인터페이스는 원하는 이름의 함수가 있는지 검색해 주고 있다면 그 함수를 호출할 수 있게 해 주는 여러 함수를 갖고 있습니다.
5. 거기에서 GetIDsOfNames 함수로 함수의 id를 얻고, Invoke 함수로 그 함수를 호출할 수 있습니다. 파라메터를 같이 넘길 수도 있습니다.

자세한 각각의 함수의 사정은 MSDN을 검색해 보시면 정확히 나와 있습니다. 저도 본의 아니게 그 도움을 많이 받았습니다.

이런 방식으로 ISSACWebSE2.dll 이라는 ActiveX 플러그인에서 issacweb_hybrid_encrypt_s 와 issacweb_decrypt_s 함수를 호출하는 프로그램은

http://home.postech.ac.kr/~octphial/posis-wrap.tar.gz

를 참고해 보십시오. (issac.c) (Depends: WINE 0.9+ ??)

일단 이런 식으로 호출이 잘 된다면 다음 단계를 시도할 수 있는데, 사실 ActiveX 함수가 또 하나의 wrapper로서 내부 함수를 호출하는 별개의 루틴이 있을 수 있습니다. 이 경우가 그런데, ActiveX 함수를 호출하면 그것들이 ISSACWLibSE2.dll 이라는 라이브러리에서 해당하는 함수를 다시 호출하는데, 처음에 이 내부 함수가 ActiveX 함수인 줄 알고 많이 고생했습니다.

각설하고, 이런 속사정을 확인하는 데에 WINE이 아주 효과적입니다. WINEDEBUG="relay,snoop" 환경변수를 주고 stderr를 로그로 뽑아내면 (e.g. WINEDEBUG="relay,snoop" ... 2> log") 많은 것을 볼 수 있습니다. 저는 이 단계로부터 내부 함수의 파라메터를 추측할 수 있었고, 그 결과로 라이브러리 dll인 ISSACWLibSE2.dll 만을 호출해 같은 역할을 하게 만들 수 있었습니다. 이 방식은 OLE/COM와 같은 복잡한 여러 단계를 생략하기 때문에 상대적으로 오래된 WINE에서도 잘 컴파일되고 실행됩니다.

1. LoadLibrary 함수로 dll을 읽습니다.
2. GetProcAddress 함수로 그 함수의 주소를 얻는데 이걸 함수 포인터 변수에 대입합니다. 이 점 때문에 함수의 프로토타입을 정확히 추측할 수 있어야 합니다. 상기 로그가 거의 유일한 힌트가 되겠습니다.
3. 그냥 함수 포인터를 잘 실행해 줍니다.

이런 방식으로 만들어진 Firefox용 대체 플러그인의 소스는

http://home.postech.ac.kr/~octphial/jacobWebSE/jacobWebSE-20060207.tar.gz

에 있습니다. (역시 issac.c) (Tested on WINE-20050725)

플러그인을 만든 방식도 다소 기록할 가치가 있는데, 원래 npruntime 이라는 간단한 예제 플러그인 (모질라 플러그인 개발자 페이지에 링크가 있습니다) 을 고쳤고, 중요한 점은 이렇습니다.

WINE과 소통하는 부분은 온전히 WINE 아래에서 실행되어야 한다고 합니다. (즉 main 프로세스부터 WINE에 의해 실행되어야 하는 상황) 이렇기 때문에 Firefox 플러그인만으로는 이 함수와 소통하기 힘듭니다. 따라서 WINE에 의존적인 함수 호출 부분은 외부 프로그램으로 하나 만들고 플러그인이 이 프로그램을 실행해 결과물을 받도록 해야 합니다. 저는 파이프를 이용해 write-only pid를 다른 인자와 함께 외부 프로그램을 실행할 때에 넘기고 그 파이프에 반환값을 쓰도록 설계했습니다.

이런 식으로 최종적으로 학교 정보 시스템에 무사히 접속했습니다.

참고로 ActiveX 플러그인 프로그래밍 부분에 대해서는 윈도에서 작동하는 모질라 ActiveX 플러그인 프로젝트 (http://www.iol.le/~locka/)를 참고해 보시는 것도 도움이 됩니다. 하지만 거기는 대체로 결과값을 반납하지 않는 Media Player 류의 프로그램 임베딩을 위한 플러그인이기 때문에, 함수의 결과값을 받는 경우에 있어서는 잘 작동하지 않았습니다. 제 경우가 그랬지요.

혹시 비슷한 경우를 겪으시게 되면 언제든지 스레드를 올려주세요. :)

오병현 배상

댓글

handrake의 이미지

고수의 오오라를 풍기시는 군요 :oops:
저는 몇 달 전에 리눅스에서 클럽박스 써보자고 이리 저리 삽질을 해본 적이 있습니다만,
octaphial님과 같은 지식이 없어서 여러 버젼 깔아보고 하는 정도 밖에 못해봤는데,
이렇게 방향을 제시해 주셔서 감사합니다. 다음 삽질에 유용한 정보가 될 것 같습니다 :twisted:

danskesb의 이미지

음 지금 저 소스를 보려고 링크를 누르니까 지워졌네요.

저도 비슷한 상황에 처해서, 소스를 다시 올려 주시면 고맙겠습니다.

---- 절취선 ----
http://blog.peremen.name

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.