겸손한 개발을 위한 자양분

앞서
WebSVN 에서 특정 저장소에 PREFIX 를 설정하여,
나타나지 않도록 하게 하였었다.

특정 저장소 리스트 숨기는 방법 보러가기

업무를 진행하다보니,
이번에는 공개된 저장소에서도 특정 폴더를
나타나지 않게 할 필요성이 있게 되었다.

WebSVN 은 저장소와 폴더(파일)의 개념이 독립적이기 때문에
수정 위치가 다르다.

다음과 같이 설정하여,
 "_preserve_" 라는 문자열로 시작되는 폴더를 숨길 수 있다.

< WebSVN \ listing.php >

function showDirFiles($svnrep, $subs, $level, $limit, $rev, $listing, $index, $treeview = true)
{
   global $rep, $passrev, $showchanged, $config, $lang;
   $path = "";
   if (!$treeview)
      $level = $limit;
   for ($n = 0; $n <= $level; $n++)
   {
      $path .= $subs[$n]."/";
   }
   $contents = $svnrep->dirContents($path, $rev);
   // List each file in the current directory
   $loop = 0;
   $last_index = 0;
   $openDir = false;
   $fullaccess = $rep->hasReadAccess($path, false);
  
   foreach($contents as $file)
   {
      $isDir = ($file{strlen($file) - 1} == "/"?1:0);
      $access = false;
      if( $isDir                              &&
          strncmp($file,"_preserve_",10) == 0 )
         continue;
      if ($isDir)
      {
         if ($rep->hasReadAccess($path.$file, true))

 ...
붉은색 코드가 추가된 부분이다.

만약, 폴더 뿐만이 아니라 파일까지 숨기고 싶다면,
위 코드 대신 아래의 코드를 삽입하면 된다.
      if( strncmp($file,"_preserve_",10) == 0 )
         continue;

마찬가지로,
특정 헤더에 설정값을 받도록 할 수 있겠지만,
귀차니즘...

끝!

osr에서 배포한 확장 모듈 사용.
KD> !osrexts.sst

사용자 삽입 이미지
 


함수 호출로 인한 스택 구성시,
처음에, 이전의 EBP 레지스터 값을 스택에 저장한다.

이를 이용해 현재의 EBP + 0x4 에서 함수의 Return Address 를 찾을 수 있다.
이 방법을 반복하여, 함수 콜 관계를 확인할 수 있다.


예제 )
void __fastcall WhoCallMe()
{
 PVOID pEBP;
 PVOID pStackFrame;
 DWORD dwReturnAddr;
 DWORD dwArgs[3];
 CHAR sMsg[512];
 //__asm mov eax, [ebp+4]
 //__asm mov dword ptr [dwReturnAddr], eax
  __asm mov  pEBP, ebp
 
 do{
 
  pStackFrame = pEBP;
  pEBP  = (PVOID)*(PDWORD)(pEBP);
  
  dwReturnAddr = *(PDWORD)((DWORD)pStackFrame +4);
  dwArgs[0] = *(PDWORD)((DWORD)pStackFrame +8);
  dwArgs[1] = *(PDWORD)((DWORD)pStackFrame +12);
  dwArgs[2] = *(PDWORD)((DWORD)pStackFrame +16);
  sprintf(sMsg, "[DBG] StackPtr:0x%08x CallAddr:0x%08x Args[0]:%08x Args[1]:%08x Args[2]:%08x\n",
   pEBP, dwReturnAddr, dwArgs[0], dwArgs[1], dwArgs[2]);
  OutputDebugString(sMsg);  
 }while(dwReturnAddr != 0);
 
}
void fnC(void *a, void *b, void *c)
{
 WhoCallMe();
 return;
}
void fnB(char a, char b)
{
 fnC((PUCHAR)1, (PUCHAR)2, (PUCHAR)3);
 return;
}
BOOL fnA(int a)
{
 fnB('1', '2');
 return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
  // TODO: Place code here.
 fnA(1);
 return 0;
}

결과
[2416] [DBG] StackPtr:0x0012ff04 CallAddr:0x004010aa Args[0]:0012ff18 Args[1]:004010ba Args[2]:00000001
[2416] [DBG] StackPtr:0x0012ff18 CallAddr:0x004010ba Args[0]:00000001 Args[1]:00000002 Args[2]:00000003
[2416] [DBG] StackPtr:0x0012ff28 CallAddr:0x004010cb Args[0]:00000031 Args[1]:00000032 Args[2]:0012ff34
[2416] [DBG] StackPtr:0x0012ff34 CallAddr:0x004010dc Args[0]:00000001 Args[1]:0012ffc0 Args[2]:00401205
[2416] [DBG] StackPtr:0x0012ffc0 CallAddr:0x00401205 Args[0]:00400000 Args[1]:00000000 Args[2]:00142426
[2416] [DBG] StackPtr:0x0012fff0 CallAddr:0x7c816ff7 Args[0]:00360033 Args[1]:00340037 Args[2]:7ffd8000
[2416] [DBG] StackPtr:0x00000000 CallAddr:0x00000000 Args[0]:00401137 Args[1]:00000000 Args[2]:78746341



단, 최적화 옵션을 사용하여, 빌드할 경우,
스택프레임을 구성하지 않을 수 있으므로,
일부 프로그램에서 실제 Call 구조와 다른 결과를 나타낼 수 있다.
( 기타 디버거 역시 갖고 있는 한계 )

서브버전과 함께 사용하는 WebSVN을 연동해보면,
SVN의 ParentPath가 모두 보이는것을 확인할 수있다.

내가 잘못알고 있어서인지
SVN 폴더 내부의 authz, svnserve.conf 파일을 수정해도
WebSVN에서는 모든 저장소가 리스트되어
보안성을 가져야하는 저장소(WebSVN에 나타나지 않지만 실제 존재하는)
문제 때문에 사용에 제약이 있었다.

웹에서도 문제 해결에 대한 답을 확인 할 수 없어
소스코드 수정으로 해결하였다.

내가 사용한 방법은,
보안성을 주려는 폴더에 특정 PREFIX를 두어
해당 PREFIX를 갖는 폴더는 화면상에 나타나는 List에
추가하지 않는것이다.

다음은 "_preserve_"라는 문자열로 시작되는 저장소를 숨기도록 수정하는 코드이다.

< WebSVN \ index.php >

if ($config->flatIndex)
{
   // Create the flat view
  
   $projects = $config->getRepositories();
   $i = 0;
   $listing = array ();
   foreach ($projects as $project)
   {
      // if ($project->hasReadAccess("/", true))      
      if ( $project->hasReadAccess("/", true)                      
&&
           strncmp($project->getDisplayName(),"_preserve_",10) != 0 )
      {
         $url = $config->getURL($project, "/", "dir");
     
         $listing[$i]["rowparity"] = $i % 2;
         $listing[$i++]["projlink"] = "<a href=\"${url}sc=$showchanged\">".$project->getDisplayName()."</a>";
      }
   }
   $vars["flatview"] = true;
   $vars["treeview"] = false;  
}
else
{
   // Create the tree view
  
   $projects = $config->getRepositories();
   reset($projects);
   $i = 0;
   $listing = array ();
   $curgroup = NULL;
   $parity = 0;
   foreach ($projects as $project)
   {
      // if ($project->hasReadAccess("/", true))      
      if ( $project->hasReadAccess("/", true)                       &&
           strncmp($project->getDisplayName(),"_preserve_",10) != 0 )

      {
         $listing[$i]["rowparity"] = $parity % 2;
         $url = $config->getURL($project, "/", "dir");
 ...
기존 코드는 주석처리하고 붉은색 코드를 추가하였다.

코드 수정 전에는 다음과 같이 모든 저장소가 표시된다.
사용자 삽입 이미지


코드 수정후에는 다음과 같이 해당 PREFIX에 대하여 숨겨진것을 확인할 수 있다.
사용자 삽입 이미지


편의에 따라 헤더파일을 생성하여,
PREFIX별 권한 설정도 가능할 것으로 판단된다.