IDA一把junction.exe, 得到一堆c代码;调整一下,得到下面的目录junction创建代码:
#include <windows.h>
#include <winioctl.h>
#include <strsafe.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
USHORT Reserved;
union {
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
ULONG Flags;
WCHAR PathBuffer[1];
} SymbolicLinkReparseBuffer;
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
WCHAR PathBuffer[1];
} MountPointReparseBuffer;
struct {
UCHAR DataBuffer[1];
} GenericReparseBuffer;
} DUMMYUNIONNAME;
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
#ifndef REPARSE_DATA_BUFFER_HEADER_SIZE
#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
#endif//REPARSE_DATA_BUFFER_HEADER_SIZE
#ifndef FSCTL_SET_REPARSE_POINT
#define FSCTL_SET_REPARSE_POINT \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#endif//FSCTL_SET_REPARSE_POINT
BOOL __cdecl JunctionHandler(PCWSTR lpPathName, PCWSTR lpFileName)
{
BOOL bRet = FALSE;
HANDLE hFile;
UCHAR NameLength;
PWSTR FilePart;
DWORD BytesReturned;
WCHAR RootPathName[4] = L"X:\\";
WCHAR NameBuffer[260] = {0};
UCHAR Buffer[sizeof(REPARSE_DATA_BUFFER) + sizeof(WCHAR)*MAX_PATH]= {0};
PREPARSE_DATA_BUFFER ReparseBuffer = (PREPARSE_DATA_BUFFER)Buffer;
WCHAR FileSystemName[MAX_PATH] = {0};
WCHAR FullFileName[260] = {0};
WCHAR FullPathName[260] = {0};
//[powered by iopfnx]
if (GetFullPathNameW(lpFileName, MAX_PATH, FullFileName, &FilePart) > 0)
{
if (GetFullPathNameW(lpPathName, MAX_PATH, FullPathName, &FilePart) > 0)
{
RootPathName[0] = FullPathName[0];
GetVolumeInformationW(RootPathName, NULL, 0, NULL, NULL, NULL, FileSystemName, MAX_PATH);
if (_wcsicmp(L"NTFS", FileSystemName) == 0)
{
StringCchPrintfW(NameBuffer, MAX_PATH, L"\\??\\%s", FullFileName);
if (CreateDirectoryW(lpPathName, NULL) == TRUE)
{
hFile = CreateFileW(lpPathName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0x2200000, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
NameLength = wcslen(NameBuffer) * sizeof(WCHAR);
// #define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) // winnt
// #define IO_REPARSE_TAG_SYMLINK (0xA000000CL) // winnt
ReparseBuffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;//IO_REPARSE_TAG_SYMLINK
ReparseBuffer->MountPointReparseBuffer.SubstituteNameOffset = 0;
ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength = NameLength;
ReparseBuffer->MountPointReparseBuffer.PrintNameOffset = NameLength + sizeof(UNICODE_NULL);
ReparseBuffer->MountPointReparseBuffer.PrintNameLength = 0;
ReparseBuffer->ReparseDataLength = sizeof(USHORT)*4 + NameLength + sizeof(UNICODE_NULL) * 2;
RtlCopyMemory(ReparseBuffer->MountPointReparseBuffer.PathBuffer, NameBuffer, NameLength);
bRet = DeviceIoControl(
hFile,
FSCTL_SET_REPARSE_POINT,
ReparseBuffer,
REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseBuffer->ReparseDataLength,
NULL,
0,
&BytesReturned,
NULL);
CloseHandle(hFile);
}
if (bRet == FALSE)
{
RemoveDirectoryW(lpPathName);
}
}
}
}
}
return bRet;
}
int __cdecl wmain(int argc, wchar_t* argv[])
{
if (argc == 3)
{
if (JunctionHandler(argv[1], argv[2]) == TRUE)
{
return 0;
}
}
printf("uasge : Junc.exe src_path dst_path\n");
return -1;
}